# Legnext AI — Complete Documentation
> Unofficial Midjourney REST API for image and video generation — production-ready, no Discord or Midjourney account required.
Base URL: `https://api.legnext.ai/api`
Auth: `x-api-key` header (get your key at https://legnext.ai/dashboard)
Free tier: 200 one-time credits, no credit card required
Pro plan: $30/month for 33,000 credits — https://legnext.ai/#pricing
This file consolidates the full Legnext AI API documentation into a single
markdown document for LLM consumption. Each section is delimited by `---`
and prefixed with its source URL on docs.legnext.ai.
---
# Overview
_Legnext AI Midjourney API features for image and video generation_
## Image Generation & Editing
### Core Features
- **[Text to Image](https://docs.legnext.ai/api-reference/image-generation/diffusion)**: Generate high-quality images from text descriptions using advanced AI models.
- **[Image Editing](https://docs.legnext.ai/api-reference/image-generation/edit)**: Edit and repaint specific areas of existing images with precision control.
- **[Regional Repaint](https://docs.legnext.ai/api-reference/image-generation/inpaint)**: Selectively modify regions using masks and targeted prompts.
- **[Background Removal](https://docs.legnext.ai/api-reference/image-generation/remove-background)**: Automatically remove backgrounds to create clean cutouts.
### Enhancement Tools
- **[Upscale](https://docs.legnext.ai/api-reference/image-generation/upscale)**: Enhance image resolution and quality with AI upscaling technology.
- **[Enhance](https://docs.legnext.ai/api-reference/image-generation/enhance)**: Improve image quality, clarity, and detail at current resolution.
- **[Variation](https://docs.legnext.ai/api-reference/image-generation/variation)**: Create controllable variations while maintaining composition structure.
- **[Remix](https://docs.legnext.ai/api-reference/image-generation/remix)**: Transform images with new prompts and controllable intensity.
### Advanced Operations
- **[Extend](https://docs.legnext.ai/api-reference/image-generation/outpaint)**: Expand images in all directions using intelligent outpainting.
- **[Pan Extend](https://docs.legnext.ai/api-reference/image-generation/pan)**: Extend images in a single specified direction with precision.
- **[Retexture](https://docs.legnext.ai/api-reference/image-generation/retexture)**: Transform materials and textures with AI-powered style transfer.
- **[Advanced Edit](https://docs.legnext.ai/api-reference/image-generation/upload-paint)**: Complex editing with custom canvas positioning and masks.
### Utility Functions
- **[Blend](https://docs.legnext.ai/api-reference/image-generation/blend)**: Combine 2-5 images into a single unique creation with seamless blending.
- **[Describe](https://docs.legnext.ai/api-reference/image-generation/describe)**: Generate detailed text descriptions and prompts from existing images.
- **[Shorten](https://docs.legnext.ai/api-reference/image-generation/shorten)**: Analyze and simplify prompts to their most essential elements.
- **[Reroll](https://docs.legnext.ai/api-reference/image-generation/reroll)**: Re-execute tasks to generate new variations with same parameters.
## Video Generation
- **[Video Diffusion](https://docs.legnext.ai/api-reference/video-generation/video-diffusion)**: Generate dynamic videos from text prompts or existing images.
- **[Extend Video](https://docs.legnext.ai/api-reference/video-generation/extend-video)**: Extend existing videos with seamless continuation and motion.
- **[Video Upscale](https://docs.legnext.ai/api-reference/video-generation/video-upscale)**: Enhance video resolution and quality using AI upscaling technology.
## Before You Start
**Important**: Please read our [Notice](https://docs.legnext.ai/getting-started/notice) before using the API to understand supported models and current limitations.
---
# Quickstart
_Get started with Legnext AI API_
## 1. Generate an API Key
Get your API key from the Legnext dashboard to authenticate your requests.
> **Warning:** Never share your API key with anyone. Keep it secure and never commit it to version control.
## 2. Set URL and Endpoint
All API requests are made to our base URL with specific endpoints:
```
https://api.legnext.ai/api/v1/{endpoint}
```
For example: `https://api.legnext.ai/api/v1/diffusion`
## 3. Headers
All API requests must include the following headers:
| Header | Required | Description |
|--------|----------|-------------|
| `x-api-key` | Yes | Your API key for authentication |
| `Content-Type` | No | Set to `application/json` |
## 4. Make Your First API Call
Generate your first image using our text-to-image endpoint:
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/diffusion" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "A beautiful sunset over mountains with vibrant colors",
"callback": "https://your-domain.com/webhook"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/diffusion"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"text": "A beautiful sunset over mountains with vibrant colors",
"callback": "https://your-domain.com/webhook"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/diffusion', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'A beautiful sunset over mountains with vibrant colors',
callback: 'https://your-domain.com/webhook'
})
});
const result = await response.json();
console.log(result);
```
## 5. Response Format
All endpoints return a Job object containing:
- `job_id`: Unique job identifier
- `status`: Processing status (pending, processing, completed, failed)
- `output`: Contains result image URLs when completed
- `meta`: Usage and timing information
- `error`: Error details if task failed
## 6. Error Codes & Handling
When a request fails, the API returns an HTTP error status code along with an error object:
```json
{
"code": 401,
"message": "Failed to verify api key",
"raw_message": "",
"detail": null
}
```
### HTTP Status Codes
| Code | Description | Solution |
|------|-------------|----------|
| `400` | Bad Request | Invalid request parameters or malformed request body. Check your input parameters |
| `401` | Unauthorized | Authentication failed. Verify your API key is valid and included in the `x-api-key` header |
| `402` | Payment Required | Insufficient credits in your account. Top up your balance or upgrade your plan |
| `403` | Forbidden | Sensitive content detected or permission denied. Review content policy guidelines |
| `413` | Payload Too Large | File size exceeds maximum limit. Reduce file size and try again |
| `422` | Unprocessable Entity | Invalid parameter values or validation failed. Check parameter formats and values |
| `429` | Too Many Requests | Rate limit exceeded. Reduce request frequency or upgrade your plan |
| `500` | Internal Server Error | Temporary server issue. The request will be automatically retried |
> **Tip:** All error responses include a `code` field matching the HTTP status code and a `message` field with a human-readable description. Check these fields to understand what went wrong.
## 7. Next Steps
- Explore our [comprehensive endpoint documentation](https://docs.legnext.ai/api-reference/image-generation/diffusion) for detailed parameters and examples
- Learn about [task status checking](https://docs.legnext.ai/api-reference/task-management/get-task) for monitoring your requests
- Browse all available [image and video generation features](https://docs.legnext.ai/getting-started/overview)
Start exploring our powerful image generation capabilities!
## Important
Please read our [Notice](https://docs.legnext.ai/getting-started/notice) before using the API to understand supported models and current limitations.
---
# Important Information
_API requirements, limitations, and supported models_
## Supported Models
The API currently supports the following models:
- **v6**
- **v6.1**
- **niji 6**
- **v7** (default)
- **v8** — add `--v 8` to your prompt. Premium tier with `--hd`, `--q 4`, and `--sv 6` (4x cost). [Sunsetting soon — see below.]
- **v8.1** — add `--v 8.1` to your prompt. HD by default at standard cost. Pro subscription required.
> **Warning:** Midjourney plans to sunset **v8.0** approximately 2 weeks after v8.1 stabilizes. We recommend migrating `--v 8` prompts to `--v 8.1` ahead of time.
## Current Limitations
The API currently does **not** support the following features:
- `--repeat` parameter
- `--personalize` parameter
- `{}` prompt arrangement syntax
- `--stealth`/`--public` parameters
## Important Usage Requirements
- **When using enhance**: The original job must be created in draft mode with parameters `--v7 --draft`
- **Draft mode**: Ultra-fast image prototyping (10x faster than normal mode) with slightly reduced quality but consuming only half the GPU resources. Use `--draft` parameter to activate.
## Supported Speed Modes
Speed modes control the GPU type used for task execution, determining task execution time. The API provides **fast mode** and **turbo mode**, with **relax mode** currently not supported.
### Fast Mode (`--fast`)
Fast mode is the default GPU speed mode where API requests are prioritized using GPU resources for processing. Usually completes image generation within 1 minute.
- **Usage**: Activated with `--fast` parameter
- **Default**: Used when no speed mode is specified
- **Processing Time**: Typically under 1 minute for standard images
### Turbo Mode (`--turbo`)
Turbo mode uses a high-performance GPU pool with processing speeds up to 4x faster than fast mode. This mode consumes double the GPU time quota and only supports v5 and above versions.
- **Usage**: Activated with `--turbo` parameter
- **Speed**: Up to 4x faster than fast mode
- **Requirements**: Only supports v5+ versions
- **Cost**: Consumes double GPU time quota
- **Status**: Experimental feature - availability and billing may change
### Factors Affecting Task Time
- **Image Resolution**: Higher resolution images require more processing time
- **Aspect Ratio**: Non-standard ratios may increase processing time
- **Model Version**: Newer models are typically faster
- **Task Type**: Generation variations or lower quality settings reduce time
- **Image Prompts**: Number of referenced images in prompts affects processing time
---
# Model Information
_Complete guide to Midjourney model versions including v6, v6.1, v7, and niji 6 - features, capabilities, and parameter support for each version_
The API provides multiple model version options covering the v6 series, v7 series, and niji series. Each model version has unique advantages in image generation quality, feature characteristics, and parameter support.
**Supported Models**: The API currently supports models **v6**, **v6.1**, **niji 6**, **v7**, **v8**, and **v8.1**, with **v7** as the default.
## Version 8.1 🆕
Version 8.1 (alpha launched April 14, 2026) refines V8 with HD output by default, restored image prompting, and improved speed. Add `--v 8.1` to your prompt to use it.
> **Note:** Midjourney plans to sunset V8.0 approximately 2 weeks after V8.1 stabilizes. We recommend migrating `--v 8` prompts to `--v 8.1` ahead of time.
### Key Improvements over V8.0
- **HD by default**: Native 2K resolution out of the box — no `--hd` flag needed
- **~40% faster than V8 HD**: V8.1 HD generates at roughly the speed V8 SD did
- **Same price as V8 SD**: V8.1 is a flat 1x credits — there is no premium tier
- **Image prompts and image weights restored**: V8.1 supports image URLs in the prompt plus `--iw` for weighting (these were unavailable in early V8.0)
- **Prompt Shortener**: Prompts that exceed length limits are automatically shortened by Midjourney before generation
- **Improved Describe**: Longer, more detailed prompt descriptions match V8's prompting style
### V8.1 Parameters
- `--ar` — aspect ratio
- `--s` / `--stylize` — stylization strength (0–1000)
- `--c` / `--chaos` — variability (0–100)
- `--w` / `--weird` — weirdness (0–3000)
- `--raw` / `--style raw` — reduced default styling
- `--exp` — experimental aesthetic
- `--sref` + `--sw` — style reference URLs and weight
- `--p` — personalization code
- `--iw` — image weight (with image URLs in prompt)
- Moodboards
### V8.1 Cost Model
- All V8.1 generations: **1x credits** (80 points / $0.08 per task)
- No premium tier — `--hd`, `--q`, and `--sv 6` either don't apply or are rejected
- Subscription required: **Developer (Pro) plan or above** — same as V8
- Turbo mode (`--turbo`) is **not supported**
### Removed in V8.1 (will be rejected)
| Removed Parameter | Why |
|---|---|
| `--q` / `--quality` | V8.1 has no quality tiers; HD is default |
| `--cref` / `--cw` | Not supported in V8.1 alpha |
| `--oref` / `--ow` | Not supported in V8.1 alpha |
| `--no` | Negative prompt is not supported in V8.1 alpha |
| `--turbo` | V8 family does not support Turbo mode |
| `--sd` | SD output is controlled via the web settings panel, not the API |
| `--hd` | Accepted but treated as a no-op (HD is already the default) |
Requests containing rejected flags receive an HTTP 400 with a message naming the offending flag.
### Feature Support
| Feature | v8 | v8.1 |
|---------|-----|------|
| Variation | Strong & Subtle | Strong & Subtle |
| Reroll | ✓ | ✓ |
| Remix | ✓ | ✓ |
| Animate (image to video) | ✓ | ✓ |
| Blend | ✓ (V8 native) | ✓ |
| Image Prompt + `--iw` | Limited | ✓ (restored) |
| Style Reference (`--sref` / `--sw`) | ✓ | ✓ |
| Personalization (`--p`) | ✓ | ✓ |
| Describe | via V7 fallback | via V7 fallback |
| Inpaint / Outpaint / Pan | Not available | Not available |
## Version 8
Version 8 (alpha launched March 17, 2026) is a generational leap in AI image generation. Add `--v 8` to your prompt to use it.
> **Warning:** Midjourney plans to sunset V8.0 approximately 2 weeks after V8.1 stabilizes. New integrations should target `--v 8.1`.
### Key Improvements
- **~5x faster generation**: Standard images complete in under 15 seconds
- **Native 2K HD resolution**: Use `--hd` for natively rendered 2K images — no upscale needed
- **Dramatically better text rendering**: Wrap text in `"quotes"` for readable signs, labels, and typography
- **Accurate hands & anatomy**: Correct finger counts, natural proportions, consistent full-body poses
- **Superior prompt adherence**: Complex multi-element compositions render with much higher fidelity
- **Enhanced coherence**: `--q 4` mode maintains visual consistency in complex scenes
- **Physically accurate lighting**: Reflections, subsurface scattering, and shadow direction are physically grounded
### V8 Parameters
- `--hd` — Native 2K resolution (4x cost)
- `--q 4` — Enhanced coherence mode (4x cost)
- `--oref` — Omni Reference, replaces `--cref` (handles both person likeness and object form)
- `--sv 6` — Use old (more accurate) SREF version (4x cost)
- All V7 parameters (`--chaos`, `--weird`, `--exp`, `--raw`, `--sref`, `--stylize`, etc.) are supported
### V8 Cost Model
- Standard V8 generation: **same cost as V7**
- Premium features (`--hd`, `--q 4`, `--sv 6`): **4x cost**
- V8 does **not** require upscaling — images are natively high resolution
- Turbo mode (`--turbo`) is **not supported** with V8
### Feature Support
| Feature | v7 | v8 |
|---------|-----|-----|
| Variation | Strong & Subtle | Strong & Subtle |
| Upscale | Subtle & Creative | Not needed (native 2K) |
| Reroll | ✓ | ✓ |
| Remix | ✓ | ✓ |
| Animate (image to video) | ✓ | ✓ |
| Blend | ✓ | ✓ (V8 native) |
| Inpaint / Outpaint / Pan | ✓ | Not available |
| Style Reference (--sref) | ✓ | ✓ (higher fidelity) |
| Personalization (--p) | ✓ | ✓ (backward compatible) |
## Version 7
Version 7 (released April 3, 2025) achieved significant breakthroughs in image generation. This version dramatically improved the processing accuracy of text and image prompts, while achieving a qualitative leap in image quality—particularly in human anatomy, hand details, and object textures.
As core innovations, V7 introduces two revolutionary features:
- **Draft Mode**: Supports rapid iterative generation
- **Universal Reference**: Provides more powerful image reference capabilities, bringing new possibilities to creative workflows
### Feature Support
| Feature | v6* | v7* |
|---------|-----|-----|
| Variation | Strong & Subtle | Strong & Subtle |
| Upscale | Subtle & Creative | Same as v6.1 |
| Extend | ✓ | Same as v6.1 |
| Outpaint | ✓ | Same as v6.1 |
| Reshape | ✓ | ✓ |
| Moodboard | ✓ | ✓ |
| Edit | ✓ | Same as v6.1 |
| Advanced Edit | ✓ | ✓ |
The quality parameter in V7 works differently. Please refer to the [Quality Parameter Documentation] for details.
## Version 6.1
Version 6.1 was released on July 30, 2024, as the current default model. It generates images with more coherent effects, more precise details and textures, and is approximately 25% faster than version 6.
## Version 6
Version 6 was released on December 20, 2023, and served as the default model from February 14 to July 30, 2024. Version 6 enhanced prompt accuracy for longer inputs, improved coherence and knowledge, and provided advanced image prompting and mixing capabilities.
## Niji 6
The Niji model is a special series within the platform, developed in collaboration with Spellbrush, focusing on Eastern and anime aesthetics and illustration styles.
Niji 6 was released on June 7, 2024, with improved Japanese text rendering capabilities, efficient processing of short Japanese text, and even the ability to render simple Chinese characters. It provides better image details, particularly in elements like anime eye structures, and resolves some minor image defects that affected a small portion of previously generated images.
## Model Parameter Comparison
The following table provides a detailed comparison of the parameters supported by each model version and their value ranges:
| Parameter | v6 | v6.1 | v7 | v8 | v8.1 | niji 6 | Video Model |
|:----------|:---|:---- |:---|:---|:-----|:-------|:------------|
| **Original Mode** | raw | raw | raw | raw | raw | raw | raw |
| **Tile** | true/false | true/false | true/false | true/false | true/false | true/false | 🚫 |
| **Chaos** | 0-100 | 0-100 | 0-100 | 0-100 | 0-100 | 0-100 | 🚫 |
| **Seed** | 0-4294967295 | 0-4294967295 | 0-4294967295 | 0-4294967295 | 0-4294967295 | 0-4294967295 | 🚫 |
| **Stop** | 10-100 | 10-100 | 10-100 | 🚫 | 🚫 | 10-100 | 🚫 |
| **Weird** | 0-3000 | 0-3000 | 0-3000 | 0-3000 | 0-3000 | 0-3000 | 🚫 |
| **Stylize** | 0-1000 | 0-1000 | 0-1000 | 0-1000 | 0-1000 | 0-1000 | 🚫 |
| **Quality** | (1, 2) | (0.5, 1, 2) | (1, 2, 4) | (1, 4) | 🚫 (removed) | (0.5, 1, 2) | 🚫 |
| **HD Mode** | 🚫 | 🚫 | 🚫 | ✓ (4x cost) | Default (no flag) | 🚫 | 🚫 |
| **Fast Mode** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| **Turbo Mode** | ✓ | ✓ | ✓ | 🚫 | 🚫 | ✓ | ✓ |
| **Relax Mode** | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
| **Image Weight** | 0-3 | 0-3 | 0-3 | 0-3 | 0-3 | 0-3 | 🚫 |
| **Negative Prompt (--no)** | 🚫 | ✓ | ✓ | ✓ | 🚫 (removed) | 🚫 | 🚫 |
| **Style Reference** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 🚫 |
| **Omni Reference (--oref)** | 🚫 | 🚫 | ✓ | ✓ | 🚫 (removed) | 🚫 | 🚫 |
| **Character Reference (--cref)** | ✓ | ✓ | ✓ | Replaced by --oref | 🚫 (removed) | ✓ | 🚫 |
| **Style Version (--sv)** | (1, 2, 3, 4) | (1, 2, 3, 4) | (1, 2, 3, 4) | 6 (legacy, 4x cost) | (1, 2, 3, 4) | (1, 2, 3, 4) | 🚫 |
| **Style Weight** | 0-1000 | 0-1000 | 0-1000 | 0-1000 | 0-1000 | 0-1000 | 🚫 |
| **Draft** | 🚫 | 🚫 | ✓ | 🚫 | 🚫 | 🚫 | 🚫 |
| **Experimental** | 🚫 | 🚫 | 0-100 | ✓ | ✓ | 🚫 | 🚫 |
| **Personalization (--p)** | 🚫 | 🚫 | ✓ | ✓ (V7 compatible) | ✓ (V7 compatible) | 🚫 | 🚫 |
| **Upscale** | Subtle & Creative | Subtle & Creative | Subtle & Creative | Not needed (native 2K) | Not needed (native 2K) | Subtle & Creative | 🚫 |
## Notes:
1. ✓ indicates support for this parameter 🚫 indicates no support for this parameter
2. v8 model: `--hd` renders natively at 2K resolution (no upscale needed). `--hd`, `--q 4`, and `--sv 6` each cost 4x credits. Turbo mode is not supported.
3. v8.1 model: HD is the default — no `--hd` flag needed. All v8.1 generations are 1x credits with no premium tier. The `--q`, `--cref` / `--cw`, `--oref` / `--ow`, and `--no` parameters are removed and will be rejected.
4. v7 model exclusive parameters: draft (Draft Mode), oref (Universal Reference), ow (Universal Reference Weight), and exp (Experimental Parameters)
5. v8 replaces `--cref` (Character Reference) with `--oref` (Omni Reference) which handles both person likeness and object form
6. Video model exclusive parameters: video (Video Mode), motion (Motion Mode), end (Video End Frame), and loop (Video Loop)
7. v6.1, v7, and v8 models support the no parameter (negative prompts); v8.1 removes it
---
# Image Parameters
_Comprehensive reference for image generation parameters including aspect ratio, style, quality, chaos, and version control for Midjourney API_
Control various parameter settings for image generation to help you create ideal image effects.
## Image Generation Parameter List
| Parameter | Format | Values/Range | Description |
|--------------------------|---------------------------|---------------------------|--------------------------------------------------------------------------------|
| Aspect Ratio | `--aspect`, `--ar` | Any ratio (e.g. 16:9, 2:3) | Images are initially square, but you can use the aspect ratio parameter to change this |
| Chaos | `--chaos`, `--c` | 0-100 (default: 0) | Use the chaos parameter to add variety to your image results. Higher values create more unusual results |
| Character Reference | `--cref` | Image URL | Want to use the same character across multiple images and scenes? You can provide character reference! **Removed in V8.1** |
| Negative Prompt | `--no` | Text description | Use the negative parameter to tell what you don't want to see in the image. **Removed in V8.1** |
| Quality | `--quality`, `--q` | 0.25, 0.5, 1, 2, 4 (default: 1) | Use the quality parameter to control image detail and processing time. V8 supports --q 4 for enhanced coherence (4x cost). **Removed in V8.1** |
| Seed | `--seed` | 0-4294967295 | Use the seed parameter for testing and experimentation. Same seed with same prompt = consistent results |
| Stop | `--stop` | 10-100 (default: 100) | Need a softer, more unique look? Use the stop parameter to finish images halfway through the process |
| Raw Mode | `--raw` | No value | Use raw mode to get more control over your images, reduces default aesthetic styling |
| Stylize | `--stylize`, `--s` | 0-1000 (default: 100) | Use the stylize parameter to control artistic style in images. Lower = more prompt-focused, Higher = more artistic |
| Style Reference | `--sref` | Image URL | Want to match the look and feel of another image? You can provide style reference! |
| Omni Reference | `--oref` | Image URL | V7+. Reference a person or object from another image. In V8, replaces --cref and handles both person likeness and object form. **Removed in V8.1** |
| Tile | `--tile` | No value | Use the tile parameter to create seamless tiled images for patterns and textures |
| Version | `--version`, `--v` | 1-8.1 (current default: 7, latest: 8.1) | Use version parameter to explore and switch between different model versions |
| HD Mode | `--hd` | No value | V8: native 2K resolution at 4x credit cost. V8.1: HD is the default — `--hd` is accepted but has no effect |
| Draft | `--draft` | No value | Generate draft images using half GPU power in V7 and above for rapid prototyping |
| Weird | `--weird`, `--w` | 0-3000 (default: 0) | Use the weird parameter to make your images strange and unconventional |
| Fast | `--fast` | No value | Switch your GPU speed to fast mode (default processing speed) |
| Image Weight | `--iw` | 0-3 (default: 1) | Control the influence of image prompts. Higher values make image prompts more influential |
| Relax | `--relax` | No value | Switch your GPU speed to relax mode (slower but uses less quota) |
| Turbo | `--turbo` | No value | Switch your GPU speed to turbo mode (4x faster, double cost, v5+ only) |
| Niji | `--niji` | 5, 6 (current: 6) | Use our focused anime and East Asian aesthetic model |
| Experimental | `--exp` | No value | Control the aesthetic effects of image generation with experimental features |
| Motion | `--motion` | 1-4 (default: 2) | Control video motion status (only supports video tasks). Higher = more motion |
### Example Usage
```
A cute kitten --ar 16:9 --stylize 100
Beautiful landscape, sunset --quality 1 --chaos 50
Portrait --cref [reference image URL] --niji
A small duck holding a magic wand --oref [object reference URL]
Dynamic explosion --chaos 75 --weird 250 --s 200
Minimalist design --raw --stylize 0 --stop 80
Mountain scenery --ar 16:9
Abstract art --stylize 500 --weird 750
```
## Advanced Prompt Techniques
### Multi-Prompts
Use double colons `::` to separate concepts and control their relative importance:
```
Hot dog:: animal --ar 16:9
Hot:: dog:: animal --ar 16:9
```
The first example treats "Hot dog" as one concept, while the second separates "Hot" and "dog" as different concepts.
### Prompt Weights
Add weights to multi-prompt sections using `::` followed by a number:
```
Beach::2 mountain forest --ar 16:9
```
This gives "Beach" twice the weight of "mountain forest" in the generation.
**Weight Examples:**
- `::2` - Double weight
- `::0.5` - Half weight
- `::-0.5` - Negative weight (reduces influence)
### Negative Prompting Examples
```
Beautiful garden --no weeds, dead plants, brown leaves
Portrait --no glasses, hat, beard
Landscape --no buildings, cars, people
```
### Advanced Parameter Combinations
**Ultra-detailed realistic photo:**
```
Professional portrait --quality 2 --stylize 50 --chaos 10
```
**Artistic and experimental:**
```
Abstract art --stylize 750 --weird 1500 --chaos 80
```
**Character consistency across images:**
```
Character design --cref [URL] --seed 12345 --stylize 200
```
**Anime style with motion:**
```
Dynamic action scene --niji 6 --motion 4 --chaos 30
```
## Supported Aspect Ratios
Core aspect ratios and their typical applications:
- **1:1** - Standard square, suitable for social media avatars, Instagram posts
- **4:3** - Traditional rectangle, suitable for older monitors, tablets
- **2:3** - Classic photography ratio, commonly used for frames, posters
- **16:9** - Modern widescreen ratio, mainstream standard for HD video, smart TVs
- **9:16** - Portrait ratio, optimized for mobile short videos, social media stories
### Setting Aspect Ratios
You can quickly determine and set image aspect ratios through these methods:
- **Based on pixel dimensions**: For 1920x1080 pixel images, input `--ar 1920:1080`, system automatically simplifies to `--ar 16:9`
- **Based on physical dimensions**: For sizes like 8.5x11 inches, remove decimal points and input `--ar 85:110`
- **Custom ratios**: Supports any integer ratios, such as `--ar 3:2` or `--ar 5:4`
### Important Notes
- Default aspect ratio is 1:1, suitable for most basic scenarios
- Only supports integer ratios, use 139:100 instead of 1.39:1
- Different model versions may have varying support for aspect ratios
- Extreme aspect ratios (like 1:10 or 10:1) are experimental features with potentially unstable results
- During HD processing, some aspect ratios may be fine-tuned for optimization
## Detailed Parameter Guidelines
### Stylize Parameter Effects
**Low Stylize (0-50):** More literal interpretation of prompts
- `--s 0`: Very literal, follows prompt closely
- `--s 25`: Slight artistic interpretation
- `--s 50`: Balanced between literal and artistic
**Medium Stylize (100-250):** Default range with good artistic balance
- `--s 100`: Default value, good balance
- `--s 200`: More artistic interpretation
- `--s 250`: Strong artistic styling
**High Stylize (300-1000):** Heavy artistic interpretation
- `--s 500`: Very artistic, may deviate from prompt
- `--s 750`: Extremely artistic
- `--s 1000`: Maximum artistic interpretation, minimal prompt adherence
### Chaos Parameter Effects
**Low Chaos (0-25):** Consistent, predictable results
- `--c 0`: Default, very consistent results
- `--c 15`: Slight variation
- `--c 25`: Moderate variation while staying on-theme
**High Chaos (50-100):** Unpredictable, varied results
- `--c 50`: Significant variation
- `--c 75`: High variation, experimental
- `--c 100`: Maximum chaos, very unpredictable results
### Quality Parameter Impact
- `--q 0.25`: 4x faster, lower detail (draft quality)
- `--q 0.5`: 2x faster, moderate detail
- `--q 1`: Default quality and speed
- `--q 2`: 2x slower, maximum detail (only v4+)
### Weird Parameter Effects
**Subtle Weird (0-250):** Slight oddness
- `--w 0`: Default, no weirdness
- `--w 100`: Slightly unusual elements
- `--w 250`: Noticeable strange elements
**Strong Weird (500-1500):** Significant strangeness
- `--w 750`: Very unusual and surreal
- `--w 1500`: Extremely weird and abstract
**Maximum Weird (2000-3000):** Extreme experimental results
- `--w 2500`: Highly abstract and bizarre
- `--w 3000`: Maximum weirdness, often unrecognizable
### Seed Parameter Usage
Seeds are useful for:
- **Consistency**: Same seed + prompt = similar results
- **Variations**: Change other parameters while keeping seed
- **Experimentation**: Test different prompts with same seed
- **Reproducibility**: Share exact results with others
**Important Notes:**
- Seeds only work with same model version
- Different aspect ratios may produce different results even with same seed
- Seeds from older model versions won't work with newer versions
## Parameter Combination Suggestions
- **High Quality Detailed Images**: `--quality 1 --stylize 250 --chaos 10`
- **Creative Experimentation**: `--chaos 75 --stylize 50 --weird 500`
- **Character Consistency**: `--cref [character image] --seed [fixed value] --chaos 0`
- **Style Matching**: `--sref [style image] --stylize 100 --iw 1.5`
- **Realistic Photography**: `--stylize 50 --quality 1 --raw`
- **Abstract Art**: `--stylize 750 --weird 1000 --chaos 80`
- **Anime/Manga Style**: `--niji 6 --stylize 200 --quality 1`
- **Multiple Variations**: `--chaos 25 --stylize 150`
## Current Limitations
The API currently does **not** support the following parameters for **image generation**:
- `--repeat` parameter
- `--bs`, `--batchsize` parameter (only supported in video functions with values [1,2,4])
- `--personalize` parameter
- `{}` prompt variation syntax
- `--stealth`/`--public` parameters
- `--video` parameter (use video-specific endpoints instead)
## Object Reference (--oref) - V7 Update
Object Reference allows you to reference an object from another image in your generation.
### Usage
Add the `--oref` parameter at the end of your prompt, followed by your image URL. You can only use one image in object reference.
**Example:**
```
A small duck holding a magic wand --oref http://image.png
```
### Important Limitations (V7)
- **Incompatible with V6.1 features**: Object reference is incompatible with features that still use V6.1 (such as inpainting or outpainting)
- **Double GPU consumption**: Using object reference consumes 2x GPU time compared to regular V7 images
- **Editing incompatibility**: Object reference images are currently incompatible with regional inpainting, pan, or outpaint. To edit these images, use the Edit interface and remove image references along with any `--oref` or `--ow` parameters
- **Speed mode incompatibility**: Object reference is currently incompatible with speed modes or `--q 4`
## Important Usage Requirements
- **When using enhance**: The original job must be created in draft mode with parameters `--v7 --draft`
- **Draft mode**: Ultra-fast image prototyping (10x faster than normal mode) with slightly reduced quality but consuming only half the GPU resources. Use `--draft` parameter to activate.
## Supported Speed Modes
Speed modes control the GPU type used for task execution, determining task execution time. The API provides **fast mode** and **turbo mode**, with **relax mode** currently not supported.
### Fast Mode (`--fast`)
Fast mode is the default GPU speed mode where API requests are prioritized using GPU resources for processing. Usually completes image generation within 1 minute.
- **Usage**: Activated with `--fast` parameter
- **Default**: Used when no speed mode is specified
- **Processing Time**: Typically under 1 minute for standard images
### Turbo Mode (`--turbo`)
Turbo mode uses a high-performance GPU pool with processing speeds up to 4x faster than fast mode. This mode consumes double the GPU time quota and only supports v5 and above versions.
- **Usage**: Activated with `--turbo` parameter
- **Speed**: Up to 4x faster than fast mode
- **Requirements**: Only supports v5+ versions
- **Cost**: Consumes double GPU time quota
- **Status**: Experimental feature - availability and billing may change
## Prompt Best Practices
### Effective Prompt Structure
1. **Subject**: What you want to see (e.g., "portrait of a woman")
2. **Style/Medium**: Art style or medium (e.g., "oil painting", "digital art")
3. **Details**: Specific details (e.g., "blue eyes, flowing hair")
4. **Environment**: Setting or background (e.g., "in a garden", "studio lighting")
5. **Parameters**: Add parameters at the end
**Example:**
```
Portrait of an elderly wizard, oil painting style, long white beard, wise eyes, wearing purple robes, mystical library background --ar 2:3 --stylize 200 --quality 1
```
### Parameter Order Recommendations
Place parameters in this order for best results:
1. Aspect ratio (`--ar`)
2. Quality (`--quality`)
3. Stylize (`--stylize`)
4. Chaos (`--chaos`)
5. Weird (`--weird`)
6. Speed mode (`--fast`, `--turbo`)
7. Model version (`--v`, `--niji`)
8. Special modes (`--raw`, `--tile`, `--draft`)
### Common Mistakes to Avoid
- **Too many conflicting parameters**: Keep combinations logical
- **Extreme parameter values**: Start with moderate values and adjust
- **Inconsistent aspect ratios**: Choose ratios that match your intended use
- **Overuse of chaos**: High chaos can make results unpredictable
- **Wrong model versions**: Use appropriate version for your style needs
---
# Video Parameters
_Video generation parameters reference_
## Video Parameter List
| Parameter | Values | Description |
|--------------------------|---------------------------|--------------------------------------------------------------------------------|
| Motion | `low`, `high` | **Low motion**: Static scenes/subtle movements (default) `--motion low`
**High motion**: Large camera movements (may produce artistic effects) `--motion high` |
| Raw | - | Use `--raw` parameter to reduce automatic system enhancements for more precise control |
| End Frame | `image url` | Use `--end [image url]` to specify the final frame of the video |
| Loop | - | Use `--loop` parameter to generate videos where the first and last frames are identical |
| Batch Size | `1`, `2`, `4` | Use `--bs [1\|2\|4]` parameter to control the number of videos generated per task |
## Example Usage
```
Create a video with high motion
--motion high
Generate a looping video with specific end frame
--loop --end https://example.com/end-frame.jpg
Create multiple videos with raw mode
--bs 4 --raw
Combine parameters for precise control
--motion low --loop --bs 2
```
## Motion Mode Options
### Low Motion Mode (`--motion low`) - Default Setting
**Characteristics:**
- Static scenes with gentle camera movements
- Subtle character actions and minimal motion
- Smooth and stable visual effects
**Suitable Scenarios:**
- Cinematic atmosphere creation
- Mood setting scenes
- Content requiring stable visual effects
**Effect Examples:**
- Slow camera pans
- Fade in/out transitions
- Subtle facial expression changes
### High Motion Mode (`--motion high`)
**Characteristics:**
- Large camera movements and rapid action changes
- Strong visual impact and dynamic effects
- More dramatic motion sequences
**Suitable Scenarios:**
- Action scenes and dynamic content
- Transition effects
- Content requiring emphasized movement
**Important Notes:**
- May cause unnatural actions or visual anomalies
- Potential issues include stuttering or visual glitches
- Use with caution for professional content
## Parameter Combination Suggestions
- **Subtle Animation**: `--motion low --loop`
- **Dynamic Scenes**: `--motion high --bs 2`
- **Precise Control**: `--raw --motion low`
- **Custom Story Arc**: `--end [image url] --motion high`
---
# Output Storage
_Image storage duration and operation validity periods_
## Storage Duration
Images generated are stored for 30 days after creation and automatically deleted thereafter. Please ensure you save your images to permanent storage before the expiration period.
## Operation Validity
Operations on generated images (e.g., upscaling, variations) are valid for 3 days post-creation.
---
# Text to Image
_Generate images from text prompts_
**Endpoint:** `POST /v1/diffusion`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `text` | string | Yes | Text prompt for image generation (1-8192 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/diffusion" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "A beautiful sunset over the snow mountains --v 7 --draft",
"callback": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/diffusion"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"text": "A beautiful sunset over the snow mountains --v 7 --draft",
"callback": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/diffusion', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'A beautiful sunset over the snow mountains --v 7 --draft',
callback: 'https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object with status "pending". The task will be processed asynchronously.
```json
{
"job_id": "789320d3-4b20-46d3-a804-6165a079176a",
"model": "midjourney",
"task_type": "diffusion",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "2025-12-17T11:08:36Z",
"started_at": "0001-01-01T00:00:00Z",
"ended_at": "0001-01-01T00:00:00Z",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** Use the `job_id` to [check task status](https://docs.legnext.ai/api-reference/task-management/get-task) and retrieve the generated images when the task is completed.
---
# Variation
_Create variations of existing images_
**Endpoint:** `POST /v1/variation`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to vary (0/1/2/3) |
| `type` | integer | Yes | Variation intensity type (0 or 1) |
| `remixPrompt` | string | No | Additional prompt for guided variation (1-8192 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Variation Types
| Type | Name | Description |
|------|------|-------------|
| 0 | Subtle | Minor changes while preserving most original elements |
| 1 | Strong | More dramatic variations with significant changes |
## Example Requests
### Subtle Variation
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/variation" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"type": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/variation"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"type": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/variation', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
type: 0,
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "340721c6-86eb-4620-ba38-8df46fb507b6",
"model": "midjourney",
"task_type": "variation",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Upscale
_Enhance image resolution and quality_
**Endpoint:** `POST /v1/upscale`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to upscale (0/1/2/3) |
| `type` | integer | Yes | Upscaling type (0 or 1) |
| `callback` | string | No | Callback URL for task completion notifications |
## Upscale Types
| Type | Name | Description | Supported Models |
|------|------|-------------|------------------|
| 0 | Subtle | Conservative enhancement preserving original details | v6, niji6, v6.1, v7 |
| 1 | Creative | More aggressive enhancement with artistic interpretation | v6, niji6, v6.1, v7 |
| 2 | 2x | 2x resolution increase (deprecated) | v5, niji5 |
| 3 | 4x | 4x resolution increase (deprecated) | v5, niji5 |
## Example Requests
### Subtle Upscale
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/upscale" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"type": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/upscale"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"type": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/upscale', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
type: 0,
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
### Creative Upscale
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/upscale" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"type": 1,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/upscale"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"type": 1,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/upscale', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
type: 1,
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "8541c46c-6af7-49a5-a5a2-dd82eae7e6c8",
"model": "midjourney",
"task_type": "upscale",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
## Upscale Types Comparison
### Subtle (Type 0)
- **Best For**: Photography, realistic images, preserving original details
- **Characteristics**:
- Minimal artistic interpretation
- Preserves original composition and style
- Clean, sharp enhancement
- Suitable for professional use
### Creative (Type 1)
- **Best For**: Artistic images, illustrations, creative projects
- **Characteristics**:
- Enhanced artistic details
- More dramatic improvement
- May add creative interpretation
- Good for artistic workflows
---
# Reroll
_Re-execute tasks with same parameters_
**Endpoint:** `POST /v1/reroll`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original task to reroll |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/reroll" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/reroll"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/reroll', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "b54ab480-be6e-470e-8eab-5af763a4f6e0",
"model": "midjourney",
"task_type": "reroll",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Blend
_Seamlessly combine 2-5 images into a single unique creation with AI-powered blending technology_
**Endpoint:** `POST /v1/blend`
Turn multiple photos into a single unique creation using /blend
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `imgUrls` | string[] | Yes | Array of 2-5 images to blend |
| `aspect_ratio` | string | Yes | Aspect ratio: `2:3`, `1:1`, or `3:2`.|
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/blend" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"imgUrls": [
"https://example.com/image1.png",
"https://example.com/image2.png"
],
"aspect_ratio": "1:1",
"callback": "https://webhook.site/your-webhook-id"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/blend"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"imgUrls": [
"https://example.com/image1.png",
"https://example.com/image2.png"
],
"aspect_ratio": "1:1",
"callback": "https://webhook.site/your-webhook-id"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
# Query result
job_id = result["job_id"]
query_url = f"https://api.legnext.ai/api/v1/job/{job_id}"
result = requests.get(query_url, headers={"x-api-key": "YOUR_API_KEY"})
output = result.json()["output"]
print("Blended image:", output["image_url"])
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/blend', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imgUrls: [
'https://example.com/image1.png',
'https://example.com/image2.png'
],
aspect_ratio: '1:1',
callback: 'https://webhook.site/your-webhook-id'
})
});
const result = await response.json();
console.log(result);
// Poll for result
const jobId = result.job_id;
let output;
while (true) {
const queryResponse = await fetch(
`https://api.legnext.ai/api/v1/job/${jobId}`,
{
headers: { 'x-api-key': 'YOUR_API_KEY' }
}
);
const data = await queryResponse.json();
if (data.status === 'completed') {
output = data.output;
break;
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
}
console.log('Blended image:', output.image_url);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "ea1aff8a-9c68-47b8-9693-9b10570a1910",
"model": "midjourney",
"task_type": "blend",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Describe
_Generate text descriptions from images_
**Endpoint:** `POST /v1/describe`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `imgUrl` | string | yes | URL link to the image |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/describe" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"imgUrl": "https://example.com/image.png",
"callback": "https://webhook.site/your-webhook-id"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/describe"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"imgUrl": "https://example.com/image.png",
"callback": "https://webhook.site/your-webhook-id"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
# Query result
job_id = result["job_id"]
query_url = f"https://api.legnext.ai/api/v1/job/{job_id}"
result = requests.get(query_url, headers={"x-api-key": "YOUR_API_KEY"})
output = result.json()["output"]
print("Description:", output["description"])
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/describe', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imgUrl: 'https://example.com/image.png',
callback: 'https://webhook.site/your-webhook-id'
})
});
const result = await response.json();
console.log(result);
// Poll for result
const jobId = result.job_id;
let output;
while (true) {
const queryResponse = await fetch(
`https://api.legnext.ai/api/v1/job/${jobId}`,
{
headers: { 'x-api-key': 'YOUR_API_KEY' }
}
);
const data = await queryResponse.json();
if (data.status === 'completed') {
output = data.output;
break;
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
}
console.log('Description:', output.description);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "54aeca4b-f443-41f3-8b94-28cbdc2e7e20",
"model": "midjourney",
"task_type": "describe",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "",
"secret": ""
}
},
"input": null,
"output": {
"promptEn": "",
"description": "",
"finalPrompt": "",
"prompts": []
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 20,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with prompt descriptions.
---
# Shorten
_Simplify prompts to essential elements_
**Endpoint:** `POST /v1/shorten`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `prompt` | string | Yes | The prompt to analyze and shorten (1-8192 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/shorten" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A cyberpunk hacker workspace filled with holographic screens, glowing code streams, mechanical keyboards, neon reflections, cables and circuit boards everywhere, volumetric lighting, ultra-detailed sci-fi aesthetic, cinematic atmosphere, inspired by Ghost in the Shell and Blade Runner, rendered in octane, 8k resolution --ar 21:9 --v 7 --style raw --q 2",
"callback": "https://webhook.site/your-webhook-id"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/shorten"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"prompt": "A cyberpunk hacker workspace filled with holographic screens, glowing code streams, mechanical keyboards, neon reflections, cables and circuit boards everywhere, volumetric lighting, ultra-detailed sci-fi aesthetic, cinematic atmosphere, inspired by Ghost in the Shell and Blade Runner, rendered in octane, 8k resolution --ar 21:9 --v 7 --style raw --q 2",
"callback": "https://webhook.site/your-webhook-id"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
# Query result
job_id = result["job_id"]
query_url = f"https://api.legnext.ai/api/v1/job/{job_id}"
result = requests.get(query_url, headers={"x-api-key": "YOUR_API_KEY"})
output = result.json()["output"]
print("Shortened prompts:", output["prompts"])
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/shorten', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'A cyberpunk hacker workspace filled with holographic screens, glowing code streams, mechanical keyboards, neon reflections, cables and circuit boards everywhere, volumetric lighting, ultra-detailed sci-fi aesthetic, cinematic atmosphere, inspired by Ghost in the Shell and Blade Runner, rendered in octane, 8k resolution --ar 21:9 --v 7 --style raw --q 2',
callback: 'https://webhook.site/your-webhook-id'
})
});
const result = await response.json();
console.log(result);
// Poll for result
const jobId = result.job_id;
let output;
while (true) {
const queryResponse = await fetch(
`https://api.legnext.ai/api/v1/job/${jobId}`,
{
headers: { 'x-api-key': 'YOUR_API_KEY' }
}
);
const data = await queryResponse.json();
if (data.status === 'completed') {
output = data.output;
break;
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
}
console.log('Shortened prompts:', output.prompts);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "48833d7a-d588-4ad9-897b-25e1ea9edff7",
"model": "midjourney",
"task_type": "shorten",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "",
"secret": ""
}
},
"input": null,
"output": {
"promptEn": "",
"description": "",
"finalPrompt": "",
"prompts": []
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 20,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with shortened prompts.
---
# Pan
_Extend images in specified direction_
**Endpoint:** `POST /v1/pan`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to extend (0/1/2/3) |
| `direction` | integer | Yes | Extension direction (0-3) |
| `scale` | float | Yes | Extension scale ratio (1.1-3.0) |
| `remixPrompt` | string | No | Text prompt for the extended area (1-8192 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Direction Values
| Value | Direction |
|-------|-----------|
| 0 | Down |
| 1 | Right |
| 2 | Up |
| 3 | Left |
## Scale Parameter
The `scale` parameter defines the ratio of the new image area to the original in the extension direction:
- **Range**: 1.1 to 3.0
- **Example**: For a 1:1 aspect ratio image extending right by 13%:
- `scale = 1.13` means the final image will be 13% wider in the specified direction
## Example Requests
### Extend Right
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/pan" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"direction": 1,
"scale": 1.5,
"remixPrompt": "a lake near the mountain",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/pan"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"direction": 1,
"scale": 1.5,
"remixPrompt": "a lake near the mountain",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/pan', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
direction: 1,
scale: 1.5,
remixPrompt: 'a lake near the mountain',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "d0caddaa-028b-4074-985e-7894b2aef5a0",
"model": "midjourney",
"task_type": "pan",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
## Technical Notes
- Extends in only one specified direction (unlike outpaint which extends in all directions)
- Scale parameter determines extension ratio (1.1-3.0)
- AI maintains visual continuity with the original image
- Use descriptive prompts to guide the content of the extended area
---
# Outpaint
_Expand images in all directions_
**Endpoint:** `POST /v1/outpaint`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to extend (0/1/2/3) |
| `scale` | float | Yes | Extension scale ratio (1.1-2.0) |
| `remixPrompt` | string | No | Text prompt for the extended areas (1-8192 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Parameters Detail
### Scale Parameter
The `scale` parameter defines how much larger the final image will be compared to the original:
- **Range**: 1.1 to 2.0
- **Example**: For a 1:1 aspect ratio image:
- `scale = 1.2` means the original image will occupy 83% of the new image (20% extension)
- `scale = 2.0` means the original image will occupy 50% of the new image (100% extension)
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/outpaint" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"scale": 1.5,
"remixPrompt": "clouds over the sky",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/outpaint"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"scale": 1.5,
"remixPrompt": "clouds over the sky",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/outpaint', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
scale: 1.5,
remixPrompt: 'clouds over the sky',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "c4e210ca-6cf1-4453-a204-00f26a8e75cc",
"model": "midjourney",
"task_type": "outpaint",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Inpaint
_Edit specific regions with masks_
**Endpoint:** `POST /v1/inpaint`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to edit (0/1/2/3) |
| `mask` | [Mask](#mask) | Yes | Regions to repaint |
| `remixPrompt` | string | No | Text prompt for the repaint area (1-8192 characters) |
| `area` | [Polygon](#polygon) | No | Single polygon area to repaint (deprecated, use mask instead) |
| `callback` | string | No | Callback URL for task completion notifications |
## Data Types
### Mask
Choose one of the following methods to define the repaint area:
| Field | Type | Description |
|-------|------|-------------|
| `areas` | [Polygon](#polygon)[] | Array of polygonal areas to repaint |
| `url` | string | Black and white mask image URL (white areas will be repainted) |
### Polygon
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Image width in pixels (500-4096) |
| `height` | integer | Image height in pixels (500-4096) |
| `points` | integer[] | Polygon coordinates in XYXY format, clockwise from top-left |
## Example Request
### Using Polygon Areas
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/inpaint" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"mask": {
"areas": [
{
"width": 500,
"height": 500,
"points": [
10,
10,
10,
100,
100,
100,
100,
10
]
}
]
},
"remixPrompt": "Add a tree in the center",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/inpaint"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"mask": {
"areas": [
{
"width": 500,
"height": 500,
"points": [
10,
10,
10,
100,
100,
100,
100,
10
]
}
]
},
"remixPrompt": "Add a tree in the center",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/inpaint', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
mask: {
areas: [
{
width: 500,
height: 500,
points: [
10,
10,
10,
100,
100,
100,
100,
10
]
}
]
},
remixPrompt: 'Add a tree in the center',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
### Using Mask Image
```json
{
"jobId": "job_12345",
"imageNo": 0,
"remixPrompt": "Add autumn leaves",
"mask": {
"url": "https://example.com/mask-image.png"
},
"callback": "https://your-domain.com/webhook"
}
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "72e20f1a-6c76-4ec5-bda2-490016056fa8",
"model": "midjourney",
"task_type": "inpaint",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Remix
_Transform images with new prompts_
**Endpoint:** `POST /v1/remix`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to remix (0/1/2/3) |
| `remixPrompt` | string | Yes | New text prompt for transformation (1-8192 characters) |
| `mode` | integer | No | Remix intensity mode (0 or 1, default: 0) |
| `callback` | string | No | Callback URL for task completion notifications |
## Remix Modes
| Mode | Type | Description |
|------|------|-------------|
| 0 | Strong | Dramatic transformation with significant changes |
| 1 | Subtle | Minor adjustments while preserving most original elements |
## Example Requests
### Strong Remix
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/remix" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"mode": 0,
"remixPrompt": "Change style to watercolor painting",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/remix"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"mode": 0,
"remixPrompt": "Change style to watercolor painting",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/remix', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '5dd94ec3-7282-4f04-9445-59e850ef1822',
imageNo: 0,
mode: 0,
remixPrompt: 'Change style to watercolor painting',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
### Subtle Remix
```json
{
"jobId": "5dd94ec3-7282-4f04-9445-59e850ef1822",
"imageNo": 0,
"remixPrompt": "Change the time of day to golden hour sunset",
"mode": 1,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "9e0f9ff3-abea-498e-a44a-157e10b28e93",
"model": "midjourney",
"task_type": "remix",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Edit
_Edit and repaint image areas_
**Endpoint:** `POST /v1/edit`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to edit (0/1/2/3) |
| `canvas` | [Canvas](#canvas) | Yes | Target canvas dimensions |
| `imgPos` | [CanvasImg](#canvasimg) | Yes | Image position relative to canvas |
| `remixPrompt` | string | Yes | Text prompt for the edit |
| `mask` | [Mask](#mask) | No | Areas to repaint on the original image |
| `callback` | string | No | Callback URL for task completion notifications |
## Data Types
### Canvas
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Canvas width in pixels |
| `height` | integer | Canvas height in pixels |
### CanvasImg
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Image width in pixels |
| `height` | integer | Image height in pixels |
| `x` | integer | Horizontal offset from canvas top-left |
| `y` | integer | Vertical offset from canvas top-left |
### Mask
| Field | Type | Description |
|-------|------|-------------|
| `areas` | [Polygon](#polygon)[] | Polygonal areas to repaint (optional) |
| `url` | string | Black and white mask image URL (optional) |
### Polygon
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Image width in pixels (500-4096) |
| `height` | integer | Image height in pixels (500-4096) |
| `points` | integer[] | Polygon coordinates in XYXY format, clockwise from top-left |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/edit" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "c6821434-5e41-408f-b42b-2562306b109c",
"imageNo": 1,
"canvas": {
"width": 1024,
"height": 1024
},
"imgPos": {
"width": 512,
"height": 512,
"x": 256,
"y": 256
},
"remixPrompt": "A beautiful landscape with mountains",
"mask": {
"areas": [
{
"width": 500,
"height": 500,
"points": [10, 10, 10, 100, 100, 100, 100, 10]
}
]
}
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/edit"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "c6821434-5e41-408f-b42b-2562306b109c",
"imageNo": 1,
"canvas": {
"width": 1024,
"height": 1024
},
"imgPos": {
"width": 512,
"height": 512,
"x": 256,
"y": 256
},
"remixPrompt": "A beautiful landscape with mountains",
"mask": {
"areas": [
{
"width": 500,
"height": 500,
"points": [10, 10, 10, 100, 100, 100, 100, 10]
}
]
}
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/edit', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: 'c6821434-5e41-408f-b42b-2562306b109c',
imageNo: 1,
canvas: {
width: 1024,
height: 1024
},
imgPos: {
width: 512,
height: 512,
x: 256,
y: 256
},
remixPrompt: 'A beautiful landscape with mountains',
mask: {
areas: [
{
width: 500,
height: 500,
points: [10, 10, 10, 100, 100, 100, 100, 10]
}
]
}
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "4017934e-35dd-4640-9585-68c224a66f3b",
"model": "midjourney",
"task_type": "edit",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Upload paint
_Advanced editing with custom uploads_
**Endpoint:** `POST /v1/upload-paint`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `imgUrl` | string | Yes | URL of the source image (max length: 1024 characters) |
| `canvas` | [Canvas](#canvas) | Yes | Target canvas dimensions |
| `imgPos` | [CanvasImg](#canvasimg) | Yes | Image position and size on canvas |
| `remixPrompt` | string | Yes | Text prompt for the editing operation |
| `mask` | [Mask](#mask) | Yes | Areas to edit on the original image |
| `callback` | string | No | Callback URL for task completion notifications |
## Data Types
### Canvas
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Canvas width in pixels |
| `height` | integer | Canvas height in pixels |
### CanvasImg
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Image width in pixels |
| `height` | integer | Image height in pixels |
| `x` | integer | Horizontal offset from canvas top-left |
| `y` | integer | Vertical offset from canvas top-left |
### Mask
| Field | Type | Description |
|-------|------|-------------|
| `areas` | [Polygon](#polygon)[] | Polygonal areas to edit (optional) |
| `url` | string | Black and white mask image URL (optional) |
### Polygon
| Field | Type | Description |
|-------|------|-------------|
| `width` | integer | Image width in pixels (500-4096) |
| `height` | integer | Image height in pixels (500-4096) |
| `points` | integer[] | Polygon coordinates in XYXY format, clockwise from top-left |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/upload-paint" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"imgUrl": "https://cdn.legnext.ai/mj/ba5d06e1-5078-4465-adc1-a4264ecdfac7_0.png",
"canvas": {
"width": 1024,
"height": 1024
},
"imgPos": {
"width": 512,
"height": 512,
"x": 256,
"y": 256
},
"mask": {
"areas": [
{
"width": 500,
"height": 500,
"points": [
10,
10,
10,
100,
100,
100,
100,
10
]
}
]
},
"remixPrompt": "A beautiful mountain scene with trees",
"callback": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/upload-paint"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"imgUrl": "https://cdn.legnext.ai/mj/ba5d06e1-5078-4465-adc1-a4264ecdfac7_0.png",
"canvas": {
"width": 1024,
"height": 1024
},
"imgPos": {
"width": 512,
"height": 512,
"x": 256,
"y": 256
},
"mask": {
"areas": [
{
"width": 500,
"height": 500,
"points": [
10,
10,
10,
100,
100,
100,
100,
10
]
}
]
},
"remixPrompt": "A beautiful mountain scene with trees",
"callback": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/upload-paint', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imgUrl: 'https://cdn.legnext.ai/mj/ba5d06e1-5078-4465-adc1-a4264ecdfac7_0.png',
canvas: {
width: 1024,
height: 1024
},
imgPos: {
width: 512,
height: 512,
x: 256,
y: 256
},
mask: {
areas: [
{
width: 500,
height: 500,
points: [
10,
10,
10,
100,
100,
100,
100,
10
]
}
]
},
remixPrompt: 'A beautiful mountain scene with trees',
callback: 'https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "aa7bd9d9-e20d-408d-b031-46cde06ee888",
"model": "midjourney",
"task_type": "upload_paint",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Retexture
_Transform image materials and textures_
**Endpoint:** `POST /v1/retexture`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `imgUrl` | string | Yes | URL of the source image (max length: 1024 characters) |
| `remixPrompt` | string | Yes | Text description of desired texture/material transformation |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Requests
### Material Transformation
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/retexture" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"imgUrl": "https://example.com/image.jpg",
"remixPrompt": "Convert to oil painting style",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/retexture"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"imgUrl": "https://example.com/image.jpg",
"remixPrompt": "Convert to oil painting style",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/retexture', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imgUrl: 'https://i.ibb.co/yc7NvSqH/kling.jpg',
remixPrompt: 'Convert to oil painting style',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "d8f6a791-4d2f-4ec4-9df2-f0abb7775143",
"model": "midjourney",
"task_type": "retexture",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 120,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
## Supported Formats
- **Image URL**: HTTPS URLs pointing to image files (max length: 1024 characters)
- **Supported Types**: JPG, PNG, WebP
- **Max File Size**: 10MB
---
# Remove Background
_Remove backgrounds from images_
**Endpoint:** `POST /v1/remove-background`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `imgUrl` | string | Yes | URL of the image to process (max length: 1024 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/remove-background" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"imgUrl": "https://example.com/image.jpg",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/remove-background"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"imgUrl": "https://example.com/image.jpg",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/remove-background', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imgUrl: 'https://i.ibb.co/yc7NvSqH/kling.jpg',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "e5a2e10b-d982-4af6-8d91-bb62f6355f36",
"model": "midjourney",
"task_type": "remove_background",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Enhance
_Improve image quality and detail_
**Endpoint:** `POST /v1/enhance`
> **Note:** **Important**: The original job must be created in draft mode. This means the original job's prompt must include the parameters: `--v 7 --draft`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original image generation task |
| `imageNo` | integer | Yes | Image number to enhance (0/1/2/3) |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/enhance" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "c6821434-5e41-408f-b42b-2562306b109c",
"imageNo": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/enhance"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "c6821434-5e41-408f-b42b-2562306b109c",
"imageNo": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/enhance', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: 'c6821434-5e41-408f-b42b-2562306b109c',
imageNo: 0,
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "06eb333e-bd6b-4eb4-a5e9-7db1f091b728",
"model": "midjourney",
"task_type": "enhance",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 80,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with image URLs.
---
# Video Diffusion
_Generate videos from text or images_
**Endpoint:** `POST /v1/video-diffusion`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
## Image-to-Video Mode
Choose one of two input methods:
**Option 1: Using existing generated image**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the source image generation task |
| `imageNo` | integer | Yes | Image number to animate (0/1/2/3) |
| `prompt` | string | No | Video generation prompt text (1-8192 characters) |
| `videoType` | integer | No | Video quality type (0: 480p, 1: 720p) |
| `callback` | string | No | Callback URL for task completion notifications |
**Option 2: Using prompt with image URL**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `prompt` | string | Yes | Video generation prompt text with image URL included, format: "[image_url] your prompt text" (1-8192 characters) |
| `videoType` | integer | No | Video quality type (0: 480p, 1: 720p) |
| `callback` | string | No | Callback URL for task completion notifications |
## Video Types
| Value | Resolution | Description |
|-------|------------|-------------|
| 0 | 480p | Standard definition (default) |
| 1 | 720p | High definition |
## Advanced Parameters
You can add these parameters to your prompt for more control over video generation:
### Motion Intensity
Control the amount of movement in the generated video:
- **Low Motion** (default): Static scenes with subtle movements
- Add `--motion low` to your prompt
- **High Motion**: Large camera movements and dramatic motion (may produce artistic effects)
- Add `--motion high` to your prompt
**Example:**
```
"https://example.com/image.jpg A cinematic landscape --motion high"
```
### Raw Mode
Reduce automatic system enhancements for more precise control over the output:
- Add `--raw` to your prompt
**Example:**
```
"https://example.com/image.jpg A peaceful sunset scene --raw"
```
### End Frame Image
Specify the final frame of your video by providing an image URL:
- Add `--end [image_url]` to your prompt
**Example:**
```
"https://example.com/start.jpg A transformation sequence --end https://example.com/end.jpg"
```
### Video Loop
Generate a video where the last frame matches the first frame, creating a seamless loop:
- Add `--loop` to your prompt
**Example:**
```
"https://example.com/image.jpg Rotating product display --loop"
```
### Batch Size
Control the number of videos generated in a single task. This affects the cost accordingly:
- Add `--bs [1|2|4]` to your prompt
- Valid values: 1, 2, or 4
- Default: 4
**Example:**
```
"https://example.com/image.jpg A dynamic animation --bs 2"
```
### Combining Parameters
You can combine multiple parameters in a single prompt:
**Example:**
```
"https://example.com/image.jpg Epic camera movement through the scene --motion high --raw --loop --bs 1"
```
## Example Requests
### Image-to-Video (Using existing image)
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/video-diffusion" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "c6821434-5e41-408f-b42b-2562306b109c",
"imageNo": 0,
"prompt": "Make this image move with gentle animation",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"videoType": 0
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/video-diffusion"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "c6821434-5e41-408f-b42b-2562306b109c",
"imageNo": 0,
"prompt": "Make this image move with gentle animation",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d",
"videoType": 0
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/video-diffusion', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: 'c6821434-5e41-408f-b42b-2562306b109c',
imageNo: 0,
prompt: 'Make this image move with gentle animation',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d',
videoType: 0
})
});
const result = await response.json();
console.log(result);
```
### Image-to-Video (Using image URL)
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/video-diffusion" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "https://example.com/image.jpg A cinematic shot of ocean waves crashing against rocks",
"videoType": 1,
"callback": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/video-diffusion"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"prompt": "https://example.com/image.jpg A cinematic shot of ocean waves crashing against rocks",
"videoType": 1,
"callback": "https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/video-diffusion', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'https://example.com/image.jpg A cinematic shot of ocean waves crashing against rocks',
videoType: 1,
callback: 'https://webhook.site/d0ca59bc-35a6-4a1e-b1b1-aea7faeb7f67'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "d55cb628-3f71-4be8-bea1-4e01319b6589",
"model": "midjourney",
"task_type": "video_diffusion",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"video_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 480,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with video URLs.
---
# Extend Video
_Extend video duration with new frames_
**Endpoint:** `POST /v1/extend-video`
Each extension adds 4 seconds to the video duration, with a maximum of 4 extensions (creating up to 21-second videos).
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original video generation task |
| `videoNo` | integer | Yes | Video number to extend (0/1/2/3) |
| `prompt` | string | No | Text prompt to guide the extension (1-8192 characters) |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/extend-video" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "b24ffa07-7b76-49a2-963e-f6c527f7cec7",
"videoNo": 0,
"prompt": "Continue with more dynamic movement and effects",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/extend-video"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "b24ffa07-7b76-49a2-963e-f6c527f7cec7",
"videoNo": 0,
"prompt": "Continue with more dynamic movement and effects",
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/extend-video', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: 'b24ffa07-7b76-49a2-963e-f6c527f7cec7',
videoNo: 0,
prompt: 'Continue with more dynamic movement and effects',
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "e41e5586-dcee-4659-ae56-dbf19d20051a",
"model": "midjourney",
"task_type": "extend_video",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"video_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 480,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with video URLs.
---
# Video Upscale
_Enhance video resolution and quality_
**Endpoint:** `POST /v1/video-upscale`
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Request Body
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID of the original video generation task |
| `videoNo` | integer | Yes | Video number to upscale (0/1/2/3) |
| `callback` | string | No | Callback URL for task completion notifications |
## Example Request
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/video-upscale" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "b24ffa07-7b76-49a2-963e-f6c527f7cec7",
"videoNo": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}'
```
```python Python
import requests
url = "https://api.legnext.ai/api/v1/video-upscale"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"jobId": "b24ffa07-7b76-49a2-963e-f6c527f7cec7",
"videoNo": 0,
"callback": "https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/video-upscale', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: 'b24ffa07-7b76-49a2-963e-f6c527f7cec7',
videoNo: 0,
callback: 'https://webhook.site/c98cb890-fb92-439f-8d60-42c8a51eb52d'
})
});
const result = await response.json();
console.log(result);
```
## Response
Returns a task object containing the task information.
```json
{
"job_id": "2cbffb65-10ac-45a2-91d4-19a19a19ab4c",
"model": "midjourney",
"task_type": "video_upscale",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"video_urls": null,
"seed": ""
},
"meta": {
"created_at": "",
"started_at": "",
"ended_at": "",
"usage": {
"type": "point",
"frozen": 480,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
> **Note:** This is the initial success response. Use the `job_id` to check the task status via the [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint to retrieve the completed result with video URLs.
---
# Topaz Upscale Image
_Upscale images to ultra-high resolutions up to 12K_
**Endpoint:** `POST /v1/enhance-upscale`
> **Note:** Supports direct image URLs or images from previous Midjourney tasks.
## Input Methods
Choose one of the following input methods:
### Option 1: Direct Image URL
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `image_url` | string | Yes | Publicly accessible image URL (HTTP/HTTPS). Supports JPEG, PNG, TIFF. Max: 100MB |
### Option 2: Midjourney Task
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobId` | string | Yes | ID from previous Midjourney task |
| `imageNo` | integer | Yes | Image index from grid (0-3) |
### Common Parameters
All enhancement requests support the following parameters:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `target_resolution` | string | `2K` | Output resolution: `HD`, `FHD`, `2K`, `4K`, `6K`, `8K`, `12K` |
| `content_type` | string | `standard` | Enhancement model: `standard`, `photo`, `illustration`, `text`, `low_res` |
| `aspect_ratio` | string | `keep` | Aspect ratio: `keep`, `1:1`, `16:9`, `9:16`, `4:5`, `5:4`, `3:2`, `2:3`, `4:3`, `3:4` |
| `crop_mode` | string | `letterbox` | Crop handling: `letterbox`, `crop`, `stretch` |
| `output_format` | string | `jpeg` | Output format: `jpeg`, `jpg`, `png`, `tiff`, `tif` |
| `face_enhancement_level` | string | `moderate` | Face enhancement: `off`, `none`, `subtle`, `moderate`, `strong` |
| `callback` | string | - | Webhook URL for completion notifications |
## Resolution Options
| Resolution | Long Edge | Credits | Cost | Recommended For |
|------------|-----------|---------|------|-----------------|
| HD/FHD | 1920px | 120 | $0.12 | Web, social media |
| 2K | 2560px | 120 | $0.12 | Web, social media (default) |
| 4K | 3840px | 160 | $0.16 | Digital displays |
| 6K | 6144px | 200 | $0.20 | Professional printing |
| 8K | 7680px | 300 | $0.30 | Large format prints |
| 12K | 12288px | 540 | $0.54 | Billboards, posters |
> **Warning:** Higher resolutions consume more credits and take longer to process. Choose the minimum resolution that meets your requirements.
## Content Type Models
| Type | Best For |
|------|----------|
| `standard` | General purpose, mixed content (default) |
| `photo` | Photographs, realistic images |
| `illustration` | Digital art, CGI, drawings |
| `text` | Documents, screenshots with text |
| `low_res` | Very low quality source images |
## Face Enhancement
| Level | Effect |
|-------|--------|
| `off` / `none` | Disabled (no faces in image) |
| `subtle` | Gentle enhancement for natural portraits |
| `moderate` | Balanced enhancement (default) |
| `strong` | Aggressive enhancement for low-quality faces |
## Examples
### Using Image URL
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/enhance-upscale" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/photo.jpg",
"target_resolution": "4K",
"content_type": "photo"
}'
```
```python Python
import requests
response = requests.post(
"https://api.legnext.ai/api/v1/enhance-upscale",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"image_url": "https://example.com/photo.jpg",
"target_resolution": "4K",
"content_type": "photo"
}
)
print(response.json())
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/enhance-upscale', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
image_url: 'https://example.com/photo.jpg',
target_resolution: '4K',
content_type: 'photo'
})
});
console.log(await response.json());
```
### Using Midjourney Task
```bash cURL
curl -X POST "https://api.legnext.ai/api/v1/enhance-upscale" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jobId": "1868588555208310784",
"imageNo": 0,
"target_resolution": "8K",
"content_type": "illustration"
}'
```
```python Python
import requests
response = requests.post(
"https://api.legnext.ai/api/v1/enhance-upscale",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"jobId": "1868588555208310784",
"imageNo": 0,
"target_resolution": "8K",
"content_type": "illustration"
}
)
print(response.json())
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/v1/enhance-upscale', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
jobId: '1868588555208310784',
imageNo: 0,
target_resolution: '8K',
content_type: 'illustration'
})
});
console.log(await response.json());
```
## Response
### Success Response
Returns a task object with the following structure:
```json
{
"job_id": "f3efd852-18ad-483d-87f2-0685a60df014",
"model": "midjourney",
"task_type": "enhance_upscale",
"status": "pending",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "",
"image_urls": null,
"seed": ""
},
"meta": {
"created_at": "2025-12-17T03:22:29+08:00",
"started_at": "0001-01-01T00:00:00Z",
"ended_at": "0001-01-01T00:00:00Z",
"usage": {
"type": "point",
"frozen": 300,
"consume": 0
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
### Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `job_id` | string | Unique task identifier (UUID) |
| `model` | string | Model used: `midjourney` |
| `task_type` | string | Task type: `enhance_upscale` |
| `status` | string | Current status: `pending`, `processing`, `completed`, `failed` |
| `config` | object | Service configuration |
| `config.service_mode` | string | Service mode: `public` |
| `config.webhook_config` | object | Webhook configuration |
| `config.webhook_config.endpoint` | string | Webhook endpoint URL (empty if not set) |
| `config.webhook_config.secret` | string | Webhook secret (empty if not set) |
| `input` | object/null | Input parameters (null for this endpoint) |
| `output` | object | Task output (empty until completed) |
| `output.image_url` | string | Primary enhanced image URL (available when `status` is `completed`) |
| `output.image_urls` | array/null | Array of enhanced image URLs (null until completed) |
| `output.seed` | string | Generation seed (empty for enhancement tasks) |
| `meta` | object | Task metadata |
| `meta.created_at` | string | Task creation timestamp (ISO 8601) |
| `meta.started_at` | string | Task start timestamp (ISO 8601, `0001-01-01T00:00:00Z` if not started) |
| `meta.ended_at` | string | Task completion timestamp (ISO 8601, `0001-01-01T00:00:00Z` if not completed) |
| `meta.usage` | object | Credit usage information |
| `meta.usage.type` | string | Usage type: `point` |
| `meta.usage.frozen` | integer | Credits frozen/reserved for this task |
| `meta.usage.consume` | integer | Credits actually consumed (0 if task failed) |
| `detail` | object/null | Additional task details (null if none) |
| `logs` | array | Processing logs (empty array) |
| `error` | object | Error information |
| `error.code` | integer | Error code (0 if successful) |
| `error.raw_message` | string | Raw error message from service (empty if successful) |
| `error.message` | string | Human-readable error message (empty if successful) |
| `error.detail` | object/null | Additional error details (null if none) |
> **Note:** Use the `job_id` to check task status via the [Get Task Status](https://docs.legnext.ai/api-reference/task-management/get-task) endpoint.
---
# Get Task
_Retrieve job status and results_
**Endpoint:** `GET /v1/job/{job_id}`
## Status Values
| Status | Description |
|--------|-------------|
| `pending` | Job is queued and waiting to be processed |
| `staged` | Job is prepared and staged for processing |
| `processing` | Job is currently being processed |
| `failed` | Job has failed due to an error |
| `completed` | Job has completed successfully |
## Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key |
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `job_id` | string | Yes | The unique identifier of the job |
## Example Request
```bash cURL
curl -X GET "https://api.legnext.ai/api/v1/job/98761286-cdc7-4085-abfe-c9f149ff722b" \
-H "x-api-key: YOUR_API_KEY"
```
```python Python
import requests
job_id = "98761286-cdc7-4085-abfe-c9f149ff722b"
url = f"https://api.legnext.ai/api/v1/job/{job_id}"
headers = {
"x-api-key": "YOUR_API_KEY"
}
response = requests.get(url, headers=headers)
result = response.json()
print(result)
```
```javascript JavaScript
const jobId = '98761286-cdc7-4085-abfe-c9f149ff722b';
const response = await fetch(`https://api.legnext.ai/api/v1/job/${jobId}`, {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY'
}
});
const result = await response.json();
console.log(result);
```
## Response
Returns the complete job information including current status and results.
```json
{
"job_id": "a616de55-6130-4e1f-b8cd-531ed0599353",
"model": "midjourney",
"task_type": "diffusion",
"status": "completed",
"config": {
"service_mode": "public",
"webhook_config": {
"endpoint": "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"secret": ""
}
},
"input": null,
"output": {
"image_url": "https://cdn.legnext.ai/temp/1760408558306.png",
"image_urls": [
"https://cdn.legnext.ai/mj/a616de55-6130-4e1f-b8cd-531ed0599353_0.png",
"https://cdn.legnext.ai/mj/a616de55-6130-4e1f-b8cd-531ed0599353_1.png",
"https://cdn.legnext.ai/mj/a616de55-6130-4e1f-b8cd-531ed0599353_2.png",
"https://cdn.legnext.ai/mj/a616de55-6130-4e1f-b8cd-531ed0599353_3.png"
],
"seed": "1904983176",
"available_actions": {
"edit": [
0,
1,
2,
3
],
"inpaint": [
0,
1,
2,
3
],
"outpaint": [
0,
1,
2,
3
],
"pan": [
0,
1,
2,
3
],
"remix": [
0,
1,
2,
3
],
"reroll": true,
"upscale": [
0,
1,
2,
3
],
"variation": [
0,
1,
2,
3
]
}
},
"meta": {
"created_at": "2025-10-14T02:22:04Z",
"started_at": "2025-10-14T02:22:06Z",
"ended_at": "2025-10-14T02:22:50Z",
"usage": {
"type": "point",
"frozen": 80,
"consume": 80
}
},
"detail": null,
"logs": [],
"error": {
"code": 0,
"raw_message": "",
"message": "",
"detail": null
}
}
```
---
# Get Account Balance
_Check account balance and credits_
**Endpoint:** `GET /account/balance`
## Overview
Check your account balance, available credits, points, and low balance alert settings.
## Request
### Headers
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `x-api-key` | string | Yes | Your API key for authentication |
### Example Request
```bash cURL
curl --location 'https://api.legnext.ai/api/account/balance' \
--header 'x-api-key: YOUR_API_KEY'
```
```python Python
import requests
url = "https://api.legnext.ai/api/account/balance"
headers = {
"x-api-key": "YOUR_API_KEY"
}
response = requests.get(url, headers=headers)
result = response.json()
print(result)
```
```javascript JavaScript
const response = await fetch('https://api.legnext.ai/api/account/balance', {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY'
}
});
const result = await response.json();
console.log(result);
```
## Response
### Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `code` | integer | Response status code (200 for success) |
| `message` | string | Response message |
| `data` | object | Account balance data |
| `data.account_id` | integer | Your account identifier |
| `data.balance_usd` | float | Current balance in USD |
| `data.available_credits` | integer | Available credits for API usage |
| `data.available_points` | integer | Available points |
| `data.alert_threshold` | integer | Low balance alert threshold in USD |
| `data.low_balance_alert` | boolean | Whether low balance alert is triggered |
| `data.updated_at` | string | Last update timestamp (ISO 8601 format) |
### Example Response
```json
{
"code": 200,
"data": {
"account_id": 1,
"balance_usd": 72.048,
"available_credits": 71000,
"available_points": 1048,
"alert_threshold": 10,
"low_balance_alert": false,
"updated_at": "2025-11-05T08:22:37.784663288Z"
},
"message": "success"
}
```
## Understanding Your Balance
- **balance_usd**: Your current account balance in US dollars
- **available_credits**: Credits that can be used for API operations
- **available_points**: Bonus points or promotional credits
- **alert_threshold**: You'll receive alerts when balance falls below this amount
- **low_balance_alert**: Indicates if your balance is currently below the threshold
## Notes
- Check your balance regularly to ensure uninterrupted service
- Set up webhook notifications for low balance alerts
- Credits are deducted based on the API operations you perform
---
# SDK Overview
_Explore Legnext SDKs for easy API integration_
Official SDKs for the Legnext AI API - Professional image and video generation.
## Available SDKs
- **[Python](https://docs.legnext.ai/sdk/python/installation)**: Official Python SDK with async support and type hints
- **[JavaScript/Node.js](https://docs.legnext.ai/sdk/javascript/installation)**: TypeScript/JavaScript SDK with axios and full type definitions
- **[Go](https://docs.legnext.ai/sdk/go/installation)**: Go SDK with context support and concurrent-safe operations
- **[Java](https://docs.legnext.ai/sdk/java/installation)**: Java SDK compatible with Java 1.8+ and Maven/Gradle
- **[PHP](https://docs.legnext.ai/sdk/php/installation)**: PHP SDK with Composer support for PHP 7.4+
- **[Ruby](https://docs.legnext.ai/sdk/ruby/installation)**: Ruby SDK with RubyGems and Bundler support
- **[C#/.NET](https://docs.legnext.ai/sdk/csharp/installation)**: .NET SDK for C# with async/await and NuGet support
- **[Rust](https://docs.legnext.ai/sdk/rust/installation)**: Rust SDK with async/await and Cargo support
---
## Why Use an SDK?
SDKs provide:
- **Type Safety** - Full type hints and IDE autocomplete
- **Error Handling** - Built-in exception handling
- **Convenience** - No manual header or auth setup
- **Best Practices** - Language-specific conventions
---
## Features
All SDKs include:
- 🚀 Easy-to-use client libraries
- 🔐 Built-in authentication handling
- 🔗 Support for all API endpoints
- ✅ Comprehensive error handling
- 📝 Complete documentation
---
# Installation
_Install the Legnext Python SDK_
## Install from PyPI
```bash
python -m pip install legnext
```
## Verify Installation
```bash
python -c "import legnext; print(legnext.__version__)"
```
## Requirements
- Python 3.10 or higher
- httpx >= 0.27.0
- pydantic >= 2.0.0
---
## Next Steps
- [Set up Authentication](https://docs.legnext.ai/sdk/python/authentication)
- [Quick Start](https://docs.legnext.ai/sdk/python/quickstart)
---
# Authentication
_Set up authentication for the Legnext Python SDK_
## Get Your API Key
1. Visit [Legnext Dashboard](https://dashboard.legnext.ai)
2. Log in to your account
3. Navigate to **API Keys** section
4. Create a new API key
5. Copy and save it securely
## Using Your API Key
### Method 1: Direct Initialization
```python
from legnext import Client
client = Client(api_key="your-api-key-here")
```
### Method 2: Environment Variable (Recommended)
Set the environment variable:
```bash
# macOS/Linux
export LEGNEXT_API_KEY="your-api-key-here"
# Windows PowerShell
$env:LEGNEXT_API_KEY="your-api-key-here"
```
Then in your code:
```python
import os
from legnext import Client
client = Client(api_key=os.getenv("LEGNEXT_API_KEY"))
```
### Method 3: .env File
Create a `.env` file:
```env
LEGNEXT_API_KEY=your-api-key-here
```
Load it in your code:
```python
from dotenv import load_dotenv
import os
from legnext import Client
load_dotenv()
client = Client(api_key=os.getenv("LEGNEXT_API_KEY"))
```
## Security Best Practices
⚠️ **Never hardcode API keys in your code**
✅ **Always use environment variables or .env files**
✅ **Add `.env` to `.gitignore` to prevent accidental commits**
✅ **Rotate keys regularly and revoke compromised ones**
---
## Next Steps
- [Quick Start](https://docs.legnext.ai/sdk/python/quickstart)
- [Image Generation API](https://docs.legnext.ai/sdk/python/image-generation)
---
# Quick Start
_Get started with the Legnext Python SDK in 5 minutes_
## 1. Install
```bash
pip install legnext
```
## 2. Set API Key
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
```python
import os
from legnext import Client
client = Client(api_key=os.getenv("LEGNEXT_API_KEY"))
# Generate image
response = client.midjourney.diffusion(
text="a beautiful sunset over mountains"
)
# Wait for completion
result = client.tasks.wait_for_completion(response.job_id)
print(f"Images: {result.output.image_urls}")
```
That's it! Your first API call is complete.
---
## Next Steps
- **Polling** - Use `client.tasks.wait_for_completion()` with `on_progress` callback
- **Webhooks** - Set `callback` parameter for async notifications
- **API Methods** - See [Image Generation](https://docs.legnext.ai/sdk/python/image-generation) reference
- **Async** - Learn about `AsyncClient` in [Task Management](https://docs.legnext.ai/sdk/python/task-management)
- **Errors** - See error handling in [Task Management](https://docs.legnext.ai/sdk/python/task-management)
---
## Common Use Cases
**Generate and upscale:**
```python
response = client.midjourney.diffusion(text="...")
result = client.tasks.wait_for_completion(response.job_id)
upscale = client.midjourney.upscale(
job_id=response.job_id,
image_no=0
)
```
**With webhook (production):**
```python
response = client.midjourney.diffusion(
text="...",
callback="https://your-api.com/webhooks/image"
)
print(f"Job {response.job_id} will post to your webhook")
```
**Async batch:**
```python
import asyncio
from legnext import AsyncClient
async with AsyncClient(api_key=os.getenv("LEGNEXT_API_KEY")) as client:
responses = await asyncio.gather(*[
client.midjourney.diffusion(text=f"prompt {i}")
for i in range(5)
])
```
---
## Learn More
- [Installation Details](https://docs.legnext.ai/sdk/python/installation)
- [Authentication Guide](https://docs.legnext.ai/sdk/python/authentication)
- [Image Generation API](https://docs.legnext.ai/sdk/python/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/python/video-generation)
- [Task Management & Error Handling](https://docs.legnext.ai/sdk/python/task-management)
---
# Image Generation
_Image generation API reference_
## diffusion(text, callback=None)
Create a new text-to-image generation task.
```python
response = client.midjourney.diffusion(
text="a serene mountain landscape at sunset",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `text` (str): Text prompt (1-8192 characters)
- `callback` (str, optional): Webhook URL
**Returns:** `TaskResponse` with `job_id` and `status`
---
---
## variation(job_id, image_no, type, remix_prompt=None, callback=None)
Create variations of a generated image.
```python
response = client.midjourney.variation(
job_id="original-job-id",
image_no=0,
type=1, # 0=Subtle, 1=Strong
remix_prompt="add more clouds",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `type` (int): Variation intensity (0=Subtle, 1=Strong)
- `remix_prompt` (str, optional): Additional guidance
- `callback` (str, optional): Webhook URL
---
## upscale(job_id, image_no, type, callback=None)
Upscale a generated image.
```python
response = client.midjourney.upscale(
job_id="original-job-id",
image_no=0,
type=1, # 0=Subtle, 1=Creative
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `type` (int): Upscaling type (0=Subtle, 1=Creative)
- `callback` (str, optional): Webhook URL
---
## reroll(job_id, callback=None)
Regenerate with the same prompt.
```python
response = client.midjourney.reroll(
job_id="original-job-id",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `callback` (str, optional): Webhook URL
---
## blend(img_urls, aspect_ratio, callback=None)
Blend 2-5 images together.
```python
response = client.midjourney.blend(
img_urls=[
"https://example.com/image1.png",
"https://example.com/image2.png"
],
aspect_ratio="1:1", # "2:3", "1:1", or "3:2"
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `img_urls` (list): List of 2-5 image URLs
- `aspect_ratio` (str): Image ratio ("2:3", "1:1", or "3:2")
- `callback` (str, optional): Webhook URL
---
## describe(img_url, callback=None)
Generate text descriptions from an image.
```python
response = client.midjourney.describe(
img_url="https://example.com/image.png",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `img_url` (str): URL of image to describe
- `callback` (str, optional): Webhook URL
---
## shorten(prompt, callback=None)
Optimize and shorten a prompt.
```python
response = client.midjourney.shorten(
prompt="a very detailed and long prompt text...",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `prompt` (str): Prompt text to optimize
- `callback` (str, optional): Webhook URL
---
## pan(job_id, image_no, direction, scale, remix_prompt=None, callback=None)
Extend image in a specific direction.
```python
response = client.midjourney.pan(
job_id="original-job-id",
image_no=0,
direction=0, # 0=Down, 1=Right, 2=Up, 3=Left
scale=1.5, # 1.1-3.0
remix_prompt="add mountains",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `direction` (int): Direction to pan (0=Down, 1=Right, 2=Up, 3=Left)
- `scale` (float): Expansion scale (1.1-3.0)
- `remix_prompt` (str, optional): Additional guidance
- `callback` (str, optional): Webhook URL
---
## outpaint(job_id, image_no, scale, remix_prompt=None, callback=None)
Expand image in all directions.
```python
response = client.midjourney.outpaint(
job_id="original-job-id",
image_no=0,
scale=1.3, # 1.1-2.0
remix_prompt="add forest background",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `scale` (float): Expansion scale (1.1-2.0)
- `remix_prompt` (str, optional): Additional guidance
- `callback` (str, optional): Webhook URL
---
## inpaint(job_id, image_no, mask, remix_prompt=None, callback=None)
Edit specific regions using a mask.
```python
with open("mask.png", "rb") as f:
mask_data = f.read()
response = client.midjourney.inpaint(
job_id="original-job-id",
image_no=0,
mask=mask_data,
remix_prompt="add a rainbow in the sky",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `mask` (bytes): Binary mask data (PNG format)
- `remix_prompt` (str, optional): Description of edits
- `callback` (str, optional): Webhook URL
---
## remix(job_id, image_no, remix_prompt, mode=None, callback=None)
Transform image with a new prompt.
```python
response = client.midjourney.remix(
job_id="original-job-id",
image_no=0,
remix_prompt="turn into a watercolor painting",
mode=0, # 0=Strong, 1=Subtle
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `remix_prompt` (str): New prompt for transformation
- `mode` (int, optional): Remix strength (0=Strong, 1=Subtle)
- `callback` (str, optional): Webhook URL
---
## edit(job_id, image_no, canvas, img_pos, remix_prompt, mask=None, callback=None)
Edit with canvas positioning.
```python
from legnext.types import Canvas, CanvasImg, Mask, Polygon
response = client.midjourney.edit(
job_id="original-job-id",
image_no=0,
canvas=Canvas(width=1024, height=1024),
img_pos=CanvasImg(width=512, height=512, x=256, y=256),
remix_prompt="change the sky to sunset colors",
mask=Mask(areas=[
Polygon(width=1024, height=1024, points=[100, 100, 500, 100, 500, 500, 100, 500])
]),
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `canvas` (Canvas): Canvas dimensions (width, height)
- `img_pos` (CanvasImg): Image positioning on canvas
- `remix_prompt` (str): Description of edits
- `mask` (Mask, optional): Mask with polygon areas
- `callback` (str, optional): Webhook URL
---
## upload_paint(img_url, canvas, img_pos, remix_prompt, mask, callback=None)
Advanced painting on uploaded images.
```python
from legnext.types import Canvas, CanvasImg, Mask
response = client.midjourney.upload_paint(
img_url="https://example.com/image.png",
canvas=Canvas(width=1024, height=1024),
img_pos=CanvasImg(width=768, height=768, x=128, y=128),
remix_prompt="add magical effects",
mask=Mask(url="https://example.com/mask.png"),
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `img_url` (str): URL of image to paint on
- `canvas` (Canvas): Canvas dimensions (width, height)
- `img_pos` (CanvasImg): Image positioning on canvas
- `remix_prompt` (str): Description of effects
- `mask` (Mask): Mask with URL
- `callback` (str, optional): Webhook URL
---
## retexture(img_url, remix_prompt, callback=None)
Change textures and surfaces.
```python
response = client.midjourney.retexture(
img_url="https://example.com/image.png",
remix_prompt="metallic and shiny surfaces",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `img_url` (str): URL of image to retexture
- `remix_prompt` (str): Texture description
- `callback` (str, optional): Webhook URL
---
## remove_background(img_url, callback=None)
Remove the background from an image.
```python
response = client.midjourney.remove_background(
img_url="https://example.com/image.png",
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `img_url` (str): URL of image to process
- `callback` (str, optional): Webhook URL
---
## enhance(job_id, image_no, callback=None)
Enhance image quality (draft to high-res).
```python
response = client.midjourney.enhance(
job_id="draft-job-id",
image_no=0,
callback="https://your-domain.com/webhook" # Optional
)
```
**Parameters:**
- `job_id` (str): Original image task ID
- `image_no` (int): Image index (0-3)
- `callback` (str, optional): Webhook URL
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/python/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/python/task-management)
---
# Video Generation
_Video generation API reference_
## video_diffusion(prompt=None, job_id=None, image_no=None, video_type=None, callback=None)
Generate a video from text prompt, image URL, or animate existing generated image.
```python
# Generate from text only
response = client.midjourney.video_diffusion(
prompt="a flowing river through mountains",
video_type=1, # Optional: 0=480p, 1=720p
callback="https://your-domain.com/webhook"
)
# Generate from image URL in prompt
response = client.midjourney.video_diffusion(
prompt="https://example.com/image.png a flowing river through mountains",
video_type=1,
callback="https://your-domain.com/webhook"
)
# Animate existing generated image
response = client.midjourney.video_diffusion(
job_id="original-image-job-id",
image_no=0,
video_type=1,
callback="https://your-domain.com/webhook"
)
```
**Parameters:**
- `prompt` (str, optional): Video prompt or "[image_url] prompt text" (1-8192 characters)
- `job_id` (str, optional): Job ID of previously generated image
- `image_no` (int, optional): Image index (0-3) when using job_id
- `video_type` (int, optional): Quality (0=480p, 1=720p)
- `callback` (str, optional): Webhook URL
**Returns:** `TaskResponse` with `job_id` and `status`
---
## extend_video(job_id, video_no, prompt=None, callback=None)
Extend an existing video.
```python
response = client.midjourney.extend_video(
job_id="original-video-job-id",
video_no=0,
prompt="continue with dramatic lighting",
callback="https://your-domain.com/webhook"
)
```
**Parameters:**
- `job_id` (str): Original video task ID
- `video_no` (int): Video index (0-3)
- `prompt` (str, optional): Extension prompt (1-8192 characters)
- `callback` (str, optional): Webhook URL
---
## video_upscale(job_id, video_no, callback=None)
Upscale video to higher resolution.
```python
response = client.midjourney.video_upscale(
job_id="original-video-job-id",
video_no=0,
callback="https://your-domain.com/webhook"
)
```
**Parameters:**
- `job_id` (str): Original video task ID
- `video_no` (int): Video index (0-3)
- `callback` (str, optional): Webhook URL
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/python/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/python/task-management)
---
# Task Management
_Task status, async/await, and error handling_
## tasks.get(job_id)
Get current task status:
```python
task = client.tasks.get(job_id="job-123")
print(f"Status: {task.status}")
```
## tasks.wait_for_completion(job_id, timeout=300, poll_interval=3, on_progress=None)
Wait for task completion:
```python
result = client.tasks.wait_for_completion(
job_id="job-123",
timeout=600,
on_progress=lambda t: print(f"Progress: {t.progress}%")
)
```
**Parameters:**
- `job_id` (str): Job ID to wait for
- `timeout` (float, optional): Max wait time in seconds (default: 300)
- `poll_interval` (float, optional): Seconds between checks (default: 3)
- `on_progress` (callable, optional): Callback on each check
---
# Async/Await
All methods support async using `AsyncClient`:
```python
import asyncio
from legnext import AsyncClient
async def main():
async with AsyncClient(api_key="your-api-key") as client:
response = await client.midjourney.diffusion(text="...")
result = await client.tasks.wait_for_completion(response.job_id)
print(result.output.image_urls)
asyncio.run(main())
```
**Batch processing example:**
```python
async with AsyncClient(api_key="your-api-key") as client:
# Start multiple jobs
responses = await asyncio.gather(*[
client.midjourney.diffusion(text=f"prompt {i}")
for i in range(5)
])
# Wait for all
results = await asyncio.gather(*[
client.tasks.wait_for_completion(r.job_id)
for r in responses
])
```
---
# Error Handling
Handle different error types:
```python
from legnext.exceptions import (
ValidationError,
AuthenticationError,
RateLimitError,
LegnextAPIError
)
try:
response = client.midjourney.diffusion(text="...")
except AuthenticationError:
print("Invalid API key")
except RateLimitError:
print("Rate limited - retry later")
except ValidationError as e:
print(f"Invalid parameters: {e.message}")
except LegnextAPIError as e:
print(f"API error: {e.message}")
```
**Exception Types:**
| Exception | HTTP | Description |
|-----------|------|-------------|
| `ValidationError` | 400 | Invalid request parameters |
| `AuthenticationError` | 401 | Invalid API key |
| `NotFoundError` | 404 | Resource not found |
| `RateLimitError` | 429 | Rate limit exceeded |
| `ServerError` | 5xx | Server error |
| `LegnextAPIError` | - | Base exception |
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/python/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/python/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/python/quickstart)
---
# Installation
_Install the Legnext JavaScript/Node.js SDK_
## Install from NPM
```bash
npm install @legnext/midjourney-sdk
```
## Requirements
- **Node.js**: Version 12 or higher
- **Package Manager**: npm or yarn
## Supported Environments
The SDK works in:
- Node.js applications
- Webpack-bundled projects
- Browserify projects
- TypeScript projects (type definitions included)
## Module Systems
Supports both:
- **CommonJS** - `require('@legnext/midjourney-sdk')`
- **ES6 Modules** - `import { ... } from '@legnext/midjourney-sdk'`
## TypeScript Support
The SDK includes full TypeScript definitions. Type declarations are automatically resolved via `package.json`.
## Verify Installation
```bash
npm list @legnext/midjourney-sdk
```
---
# Authentication
_Set up authentication for the Legnext JavaScript SDK_
## Get Your API Key
1. Visit [Legnext Dashboard](https://dashboard.legnext.ai)
2. Log in to your account
3. Navigate to **API Keys** section
4. Create a new API key
5. Copy and save it securely
## Using Your API Key
### Method 1: Direct Initialization
```javascript
const { Configuration, ImageApi } = require('@legnext-api/js-sdk');
const config = new Configuration({
basePath: 'https://api.legnext.ai'
});
const imageApi = new ImageApi(config);
const apiKey = 'your-api-key-here';
// Use apiKey as first parameter in method calls
```
**TypeScript:**
```typescript
import { Configuration, ImageApi } from '@legnext-api/js-sdk';
const config = new Configuration({
basePath: 'https://api.legnext.ai'
});
const imageApi = new ImageApi(config);
const apiKey: string = 'your-api-key-here';
// Use apiKey as first parameter in method calls
```
### Method 2: Environment Variable (Recommended)
Set the environment variable:
```bash
# macOS/Linux
export LEGNEXT_API_KEY="your-api-key-here"
# Windows CMD
set LEGNEXT_API_KEY=your-api-key-here
# Windows PowerShell
$env:LEGNEXT_API_KEY="your-api-key-here"
```
Then in your code:
```javascript
const apiKey = process.env.LEGNEXT_API_KEY;
const imageApi = new ImageApi(apiClient);
// Use apiKey in method calls
```
### Method 3: .env File (Node.js)
Create a `.env` file:
```env
LEGNEXT_API_KEY=your-api-key-here
LEGNEXT_BASE_URL=https://api.legnext.ai
```
Install and use dotenv:
```bash
npm install dotenv
```
```javascript
require('dotenv').config();
const { Configuration, ImageApi } = require('@legnext-api/js-sdk');
const config = new Configuration({
basePath: process.env.LEGNEXT_BASE_URL || 'https://api.legnext.ai'
});
const imageApi = new ImageApi(config);
const apiKey = process.env.LEGNEXT_API_KEY;
```
### Method 4: ES Modules
```javascript
import 'dotenv/config';
import { Configuration, ImageApi } from '@legnext-api/js-sdk';
const config = new Configuration({
basePath: process.env.LEGNEXT_BASE_URL || 'https://api.legnext.ai'
});
const imageApi = new ImageApi(config);
const apiKey = process.env.LEGNEXT_API_KEY;
```
## Security Best Practices
⚠️ **Never hardcode API keys in your code**
✅ **Always use environment variables**
✅ **Add `.env` to `.gitignore`**
✅ **Never expose API keys in client-side JavaScript**
✅ **Rotate keys regularly and revoke compromised ones**
---
## Next Steps
- [Quick Start](https://docs.legnext.ai/sdk/javascript/quickstart)
- [Image Generation API](https://docs.legnext.ai/sdk/javascript/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/javascript/video-generation)
---
# Quick Start
_Get started with the Legnext JavaScript/Node.js SDK_
## 1. Install
```bash
npm install @legnext/midjourney-sdk
```
## 2. Set API Key
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
### JavaScript (CommonJS)
```javascript
const { Configuration, ImageGenerationApi } = require('@legnext/midjourney-sdk');
const config = new Configuration({
apiKey: process.env.LEGNEXT_API_KEY,
basePath: 'https://api.legnext.ai'
});
const api = new ImageGenerationApi(config);
// Generate image
api.generateImage({
text: "a beautiful sunset over mountains"
}).then(response => {
console.log('Job ID:', response.data.job_id);
}).catch(error => {
console.error('Error:', error);
});
```
### TypeScript (ES6)
```typescript
import { Configuration, ImageGenerationApi } from '@legnext/midjourney-sdk';
const config = new Configuration({
apiKey: process.env.LEGNEXT_API_KEY!,
basePath: 'https://api.legnext.ai'
});
const api = new ImageGenerationApi(config);
// Generate image
const response = await api.generateImage({
text: "a beautiful sunset over mountains"
});
console.log('Job ID:', response.data.job_id);
```
## 4. Check Task Status
```javascript
const { TaskManagementApi } = require('@legnext/midjourney-sdk');
const taskApi = new TaskManagementApi(config);
// Get task status
taskApi.getTaskStatus(jobId).then(response => {
console.log('Status:', response.data.status);
console.log('Images:', response.data.output?.image_urls);
}).catch(error => {
console.error('Error:', error);
});
```
## Available APIs
- `ImageGenerationApi` - Text to image, variations, upscaling, editing
- `VideoGenerationApi` - Video generation and upscaling
- `TaskManagementApi` - Check task status
- `AccountManagementApi` - Account balance and information
## Learn More
For complete API reference, see the generated `docs/` folder in the package.
---
# Image Generation
_Image generation API reference for JavaScript SDK_
## apiV1DiffusionPost()
Create a new text-to-image generation task.
```javascript
const { Configuration, ImageApi } = require('@legnext-api/js-sdk');
const config = new Configuration({
basePath: 'https://api.legnext.ai'
});
const imageApi = new ImageApi(config);
const apiKey = 'your-api-key-here';
const body = {
text: 'a serene mountain landscape at sunset',
callback: 'https://your-domain.com/webhook' // Optional
};
imageApi.apiV1DiffusionPost(apiKey, body, (error, data, response) => {
if (error) {
console.error('Error:', error);
} else {
console.log('Job ID:', data.job_id);
}
});
```
**Promise-based:**
```javascript
imageApi.apiV1DiffusionPost(apiKey, body)
.then(response => {
console.log('Job ID:', response.data.job_id);
})
.catch(error => {
console.error('Error:', error);
});
```
**Async/Await:**
```javascript
async function generateImage() {
try {
const response = await imageApi.apiV1DiffusionPost(apiKey, body);
console.log('Job ID:', response.data.job_id);
} catch (error) {
console.error('Error:', error);
}
}
```
**Parameters:**
- `xApiKey` (String): Your API key
- `body` (Object): Request body with:
- `text` (String): Text prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL
**Returns:** Promise resolving to response with `job_id` and `status`
---
## apiV1VaryPost()
Create variations of a generated image.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
type: 1, // 0=Subtle, 1=Strong
remixPrompt: 'add more clouds' // Optional
};
const response = await imageApi.apiV1VaryPost(apiKey, body);
console.log('Variation Job ID:', response.jobId);
```
---
## apiV1UpscalePost()
Upscale a generated image.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
type: 1 // 0=Subtle, 1=Creative
};
const response = await imageApi.apiV1UpscalePost(apiKey, body);
console.log('Upscale Job ID:', response.jobId);
```
---
## apiV1RerollPost()
Regenerate with the same prompt.
```javascript
const body = {
jobId: 'original-job-id'
};
await imageApi.apiV1RerollPost(apiKey, body);
```
---
## apiV1BlendPost()
Blend 2-5 images together.
```javascript
const body = {
imgUrls: [
'https://example.com/image1.png',
'https://example.com/image2.png'
],
aspect_ratio: '1:1', // "2:3", "1:1", or "3:2"
callback: 'https://your-domain.com/webhook'
};
await imageApi.apiV1BlendPost(apiKey, body);
```
---
## apiV1DescribePost()
Generate text descriptions from an image.
```javascript
const body = {
imgUrl: 'https://example.com/image.png'
};
await imageApi.apiV1DescribePost(apiKey, body);
```
---
## apiV1EditPost()
Edit an image by positioning it on a canvas and filling empty areas.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
canvas: {
width: 1024,
height: 1024
},
imgPos: {
width: 512,
height: 512,
x: 256,
y: 256
},
remixPrompt: 'A beautiful landscape with mountains',
callback: 'https://your-domain.com/webhook'
};
await imageApi.apiV1EditPost(apiKey, body);
```
---
## apiV1InpaintPost()
Fill masked regions in an image.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
mask: {
areas: [
{
width: 500,
height: 500,
points: [10, 10, 10, 100, 100, 100, 100, 10] // XYXY coordinates (clockwise)
}
]
},
remixPrompt: 'Add a tree in the center', // Optional
callback: 'https://your-domain.com/webhook'
};
await imageApi.apiV1InpaintPost(apiKey, body);
```
---
## apiV1OutpaintPost()
Extend image boundaries by scaling.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
scale: 1.5, // Extension scale ratio (1.1 to 2.0)
remixPrompt: 'clouds over the sky', // Optional
callback: 'https://your-domain.com/webhook'
};
await imageApi.apiV1OutpaintPost(apiKey, body);
```
---
## apiV1PanPost()
Create panoramic or panned views.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
direction: 1, // 0=Down, 1=Right, 2=Up, 3=Left
scale: 1.5, // Extension scale ratio (1.1 to 3.0)
remixPrompt: 'a lake near the mountain', // Optional
callback: 'https://your-domain.com/webhook'
};
await imageApi.apiV1PanPost(apiKey, body);
```
---
## apiV1RemixPost()
Remix an image with a new prompt and style intensity.
```javascript
const body = {
jobId: 'original-job-id',
imageNo: 0,
remixPrompt: 'Change style to watercolor painting',
mode: 0, // 0=Strong, 1=Subtle
callback: 'https://your-domain.com/webhook'
};
await imageApi.apiV1RemixPost(apiKey, body);
```
---
## apiV1ShortenPost()
Optimize and simplify prompts.
```javascript
const body = {
prompt: 'your very long and detailed prompt here...'
};
const response = await imageApi.apiV1ShortenPost(apiKey, body);
console.log('Optimized prompt:', response.shortenedPrompt);
```
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/javascript/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/javascript/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/javascript/quickstart)
---
# Video Generation
_Video generation API reference for JavaScript SDK_
## apiV1VideoDiffusionPost()
Generate a video from text prompt or animate an existing image.
```javascript
const { Configuration, VideoApi } = require('@legnext-api/js-sdk');
const apiClient = new Configuration();
apiClient.basePath = 'https://api.legnext.ai';
const videoApi = new VideoApi(apiClient);
const apiKey = 'your-api-key-here';
// Text-to-video
const body = {
prompt: 'a flowing river through mountains',
videoType: 1, // 0=480p (faster), 1=720p (higher quality)
callback: 'https://your-domain.com/webhook'
};
const response = await videoApi.apiV1VideoDiffusionPost(apiKey, body);
console.log('Job ID:', response.jobId);
```
**Image-to-video animation (from generated image):**
```javascript
// Animate a specific image from a generation task
const body = {
jobId: 'original-job-id',
imageNo: 0, // Image number (0-3)
prompt: 'flowing water animation',
videoType: 1,
callback: 'https://your-domain.com/webhook'
};
const response = await videoApi.apiV1VideoDiffusionPost(apiKey, body);
```
**Image-to-video animation (from image URL):**
```javascript
// Animate an existing image by URL
const body = {
prompt: 'https://example.com/image.png a flowing river through mountains',
videoType: 1,
callback: 'https://your-domain.com/webhook'
};
const response = await videoApi.apiV1VideoDiffusionPost(apiKey, body);
```
**Parameters:**
- `prompt` (String): Video prompt or "[image_url] prompt text" (1-8192 characters)
- `videoType` (Number): Quality (0=480p, 1=720p)
- `jobId` (String, optional): For animating from existing generation task
- `imageNo` (Number, optional): Image number (0-3) when using jobId
- `callback` (String): Webhook URL
**Returns:** Promise resolving to response with `job_id` and `status`
---
## apiV1ExtendVideoPost()
Extend an existing video.
```javascript
const body = {
jobId: 'original-video-job-id',
videoNo: 0, // Video number (0-3)
prompt: 'continue with dramatic lighting', // Optional
callback: 'https://your-domain.com/webhook'
};
const response = await videoApi.apiV1ExtendVideoPost(apiKey, body);
console.log('Extended video Job ID:', response.jobId);
```
**Parameters:**
- `jobId` (String): Original video task ID
- `videoNo` (Number): Video number (0-3)
- `prompt` (String, optional): Extension prompt (1-8192 characters)
- `callback` (String): Webhook URL
---
## apiV1VideoUpscalePost()
Upscale video to higher resolution.
```javascript
const body = {
jobId: 'original-video-job-id',
videoNo: 0, // Video number (0-3)
callback: 'https://your-domain.com/webhook'
};
const response = await videoApi.apiV1VideoUpscalePost(apiKey, body);
console.log('Upscaled video Job ID:', response.jobId);
```
**Parameters:**
- `jobId` (String): Original video task ID
- `videoNo` (Number): Video number (0-3)
- `callback` (String): Webhook URL
---
## Complete Example
```javascript
const { Configuration, VideoApi } = require('@legnext-api/js-sdk');
async function generateAndExtendVideo() {
const apiClient = new Configuration();
apiClient.basePath = 'https://api.legnext.ai';
const videoApi = new VideoApi(apiClient);
const apiKey = process.env.LEGNEXT_API_KEY;
try {
// Step 1: Generate initial video
const body = {
prompt: 'a sunset over ocean waves',
videoType: 1
};
const initialResponse = await videoApi.apiV1VideoDiffusionPost(apiKey, body);
const jobId = initialResponse.jobId;
console.log('Initial video job:', jobId);
// Wait for completion (see task-management.mdx)
// await waitForCompletion(jobId);
// Step 2: Extend the video
const extendBody = {
jobId: jobId,
videoNo: 0,
prompt: 'zoom in on the waves'
};
const extendResponse = await videoApi.apiV1ExtendVideoPost(apiKey, extendBody);
console.log('Extended video job:', extendResponse.jobId);
} catch (error) {
console.error('Error:', error);
}
}
generateAndExtendVideo();
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/javascript/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/javascript/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/javascript/quickstart)
---
# Task Management
_Task status, polling, and error handling for JavaScript SDK_
## apiV1JobJobIdGet()
Get current task status:
```javascript
const { Configuration, ImageApi } = require('@legnext-api/js-sdk');
const apiClient = new Configuration();
apiClient.basePath = 'https://api.legnext.ai';
const imageApi = new ImageApi(apiClient);
const apiKey = 'your-api-key-here';
const jobId = 'job-123';
const task = await imageApi.apiV1JobJobIdGet(jobId, apiKey);
console.log('Status:', task.status);
console.log('Progress:', task.progress + '%');
if (task.status === 'completed') {
console.log('Result:', task.output);
}
```
---
## Polling for Completion
Wait for task completion with polling:
```javascript
async function waitForCompletion(
api,
jobId,
apiKey,
timeoutSeconds = 300,
pollIntervalSeconds = 3
) {
const startTime = Date.now();
const timeout = timeoutSeconds * 1000;
while (true) {
const task = await api.apiV1JobJobIdGet(jobId, apiKey);
console.log('Current status:', task.status);
if (task.status === 'completed') {
console.log('Task completed successfully!');
console.log('Output:', task.output);
return task;
} else if (task.status === 'failed') {
throw new Error(`Task failed: ${task.error}`);
}
// Check timeout
if (Date.now() - startTime > timeout) {
throw new Error(`Task timeout after ${timeoutSeconds} seconds`);
}
// Wait before next poll
await new Promise(resolve => setTimeout(resolve, pollIntervalSeconds * 1000));
}
}
```
**Usage:**
```javascript
try {
const result = await waitForCompletion(imageApi, jobId, apiKey, 300, 3);
console.log('Final result:', result);
} catch (error) {
console.error('Error:', error.message);
}
```
---
## Complete Example with Error Handling
```javascript
const { Configuration, ImageApi } = require('@legnext-api/js-sdk');
async function generateImageWithPolling() {
const apiClient = new Configuration();
apiClient.basePath = 'https://api.legnext.ai';
const imageApi = new ImageApi(apiClient);
const apiKey = process.env.LEGNEXT_API_KEY;
try {
// Step 1: Start generation
const body = {
text: 'a beautiful sunset over mountains'
};
const response = await imageApi.apiV1DiffusionPost(apiKey, body);
const jobId = response.jobId;
console.log('Job started:', jobId);
// Step 2: Poll for completion
const result = await waitForCompletion(imageApi, jobId, apiKey, 600, 3);
// Step 3: Get final result
console.log('Image URLs:', result.output.imageUrls);
} catch (error) {
handleError(error);
}
}
function handleError(error) {
if (error.status) {
const statusCode = error.status;
const errorBody = error.response?.body;
switch (statusCode) {
case 400:
console.error('Validation error:', errorBody);
break;
case 401:
console.error('Authentication error: Invalid API key');
break;
case 404:
console.error('Resource not found:', errorBody);
break;
case 429:
console.error('Rate limit exceeded. Please retry later.');
break;
case 500:
case 502:
case 503:
console.error('Server error:', errorBody);
break;
default:
console.error(`API error (${statusCode}):`, errorBody);
}
} else {
console.error('Unexpected error:', error.message);
}
}
generateImageWithPolling();
```
---
## Error Handling
**Common HTTP Status Codes:**
| Status Code | Description | Action |
|-------------|-------------|--------|
| 400 | Invalid request parameters | Check request body format |
| 401 | Invalid API key | Verify API key is correct |
| 404 | Resource not found | Check job ID exists |
| 429 | Rate limit exceeded | Wait and retry with backoff |
| 500/502/503 | Server error | Retry with exponential backoff |
**Handling Different Error Scenarios:**
```javascript
async function callWithRetry(apiCall, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await apiCall();
} catch (error) {
if (error.status === 429) {
// Rate limited - wait and retry
await new Promise(resolve => setTimeout(resolve, 5000));
continue;
} else if (error.status >= 500) {
// Server error - exponential backoff
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
if (i === maxRetries - 1) throw error; // Last retry
continue;
} else {
// Other errors - don't retry
throw error;
}
}
}
}
// Usage
try {
const response = await callWithRetry(() =>
imageApi.apiV1DiffusionPost(apiKey, body)
);
} catch (error) {
console.error('Failed after retries:', error);
}
```
---
## Async Operations with Promise.all
For concurrent operations:
```javascript
async function generateMultipleImages() {
const apiClient = new Configuration();
apiClient.basePath = 'https://api.legnext.ai';
const imageApi = new ImageApi(apiClient);
const apiKey = process.env.LEGNEXT_API_KEY;
const prompts = ['sunset', 'mountains', 'ocean'];
try {
// Start all generations concurrently
const promises = prompts.map(async (prompt) => {
const body = { text: prompt };
const response = await imageApi.apiV1DiffusionPost(apiKey, body);
// Wait for each to complete
const result = await waitForCompletion(
imageApi,
response.jobId,
apiKey,
600,
3
);
return result.output.imageUrls[0];
});
const imageUrls = await Promise.all(promises);
imageUrls.forEach((url, index) => {
console.log(`Image ${index + 1}:`, url);
});
} catch (error) {
console.error('Error:', error);
}
}
generateMultipleImages();
```
---
## Progress Callbacks
```javascript
async function waitForCompletionWithProgress(
api,
jobId,
apiKey,
onProgress,
timeoutSeconds = 300,
pollIntervalSeconds = 3
) {
const startTime = Date.now();
const timeout = timeoutSeconds * 1000;
while (true) {
const task = await api.apiV1JobJobIdGet(jobId, apiKey);
// Call progress callback
if (onProgress) {
onProgress(task.progress || 0, task.status);
}
if (task.status === 'completed') {
return task;
} else if (task.status === 'failed') {
throw new Error(`Task failed: ${task.error}`);
}
if (Date.now() - startTime > timeout) {
throw new Error(`Task timeout after ${timeoutSeconds} seconds`);
}
await new Promise(resolve => setTimeout(resolve, pollIntervalSeconds * 1000));
}
}
// Usage
const result = await waitForCompletionWithProgress(
imageApi,
jobId,
apiKey,
(progress, status) => {
console.log(`Progress: ${progress}% - Status: ${status}`);
}
);
```
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/javascript/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/javascript/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/javascript/quickstart)
---
# Installation
_Install the Legnext Go SDK_
## Install Package
```bash
go get github.com/legnext-ai/sdks/sdks/go
```
## Requirements
- **Go**: Version 1.16 or higher
## Dependencies
The SDK requires these dependencies:
```bash
go get github.com/stretchr/testify/assert
go get golang.org/x/net/context
```
## Import Package
```go
import legnext "github.com/legnext-ai/sdks/sdks/go"
```
## Verify Installation
```bash
go list -m github.com/legnext-ai/sdks/sdks/go
```
---
# Authentication
_Set up API authentication for Go SDK_
## Getting Your API Key
1. Visit [Legnext.ai Dashboard](https://legnext.ai/dashboard)
2. Navigate to API Keys section
3. Generate a new API key
4. Copy and store securely
## Authentication Methods
### Method 1: Environment Variables (Recommended)
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key-here"
```
Then use it in your Go code:
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
// Configure API client
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
// Add API key from environment variable
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Now you can use the client
// ...
}
```
### Method 2: Direct Initialization
Hardcode the API key directly (not recommended for production):
```go
package main
import (
"context"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
// Add API key directly
config.AddDefaultHeader("x-api-key", "your-api-key-here")
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Use the client
// ...
}
```
### Method 3: Configuration File
Load API key from a configuration file:
```go
package main
import (
"context"
"encoding/json"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
type Config struct {
APIKey string `json:"api_key"`
}
func loadConfig(path string) (*Config, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var config Config
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
if err != nil {
return nil, err
}
return &config, nil
}
func main() {
// Load configuration
cfg, err := loadConfig("config.json")
if err != nil {
fmt.Printf("Error loading config: %v\n", err)
return
}
// Configure API client
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
config.AddDefaultHeader("x-api-key", cfg.APIKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Use the client
// ...
}
```
**config.json:**
```json
{
"api_key": "your-api-key-here"
}
```
### Method 4: Using godotenv
Use the `godotenv` package to load from `.env` files:
```bash
go get github.com/joho/godotenv
```
```go
package main
import (
"context"
"fmt"
"log"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
"github.com/joho/godotenv"
)
func main() {
// Load .env file
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
// Configure API client
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
if apiKey == "" {
log.Fatal("LEGNEXT_API_KEY not set")
}
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Use the client
// ...
}
```
**.env file:**
```
LEGNEXT_API_KEY=your-api-key-here
```
---
## Security Best Practices
1. **Never commit API keys to version control**
- Add `.env` and `config.json` to `.gitignore`
- Use environment variables in production
2. **Use environment variables in production**
```bash
# Set in your deployment environment
export LEGNEXT_API_KEY="your-production-key"
```
3. **Rotate keys regularly**
- Generate new keys periodically
- Revoke old keys after rotation
4. **Use different keys for development and production**
```go
var apiKey string
if os.Getenv("ENVIRONMENT") == "production" {
apiKey = os.Getenv("LEGNEXT_PROD_API_KEY")
} else {
apiKey = os.Getenv("LEGNEXT_DEV_API_KEY")
}
```
5. **Restrict API key permissions**
- Use the minimum required permissions
- Monitor usage through the dashboard
---
## Testing Authentication
Verify your API key is working:
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Test with account balance endpoint
balance, httpRes, err := client.AccountManagementAPI.ApiAccountBalanceGet(ctx).XApiKey(apiKey).Execute()
if err != nil {
if httpRes != nil && httpRes.StatusCode == 401 {
fmt.Println("❌ Authentication failed: Invalid API key")
} else {
fmt.Printf("❌ Error: %v\n", err)
}
return
}
fmt.Println("✅ Authentication successful!")
if balance.Data != nil {
fmt.Printf("Balance: $%.2f\n", *balance.Data.BalanceUsd)
}
}
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/go/image-generation)
- [Video Generation](https://docs.legnext.ai/sdk/go/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/go/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/go/quickstart)
---
# Quick Start
_Get started with the Legnext Go SDK_
## 1. Install
```bash
go get github.com/legnext-ai/sdks/sdks/go
```
## 2. Set API Key
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
// Configure API client
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
config.AddDefaultHeader("x-api-key", os.Getenv("LEGNEXT_API_KEY"))
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Generate image
request := legnext.DiffusionRequest{
Text: "a beautiful sunset over mountains",
}
response, httpRes, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Job ID: %s\n", *response.JobId)
fmt.Printf("Status: %s\n", *response.Status)
}
```
## 4. Check Task Status
```go
// Get task status
taskResponse, httpRes, err := client.VideoAPI.ApiV1JobJobIdGet(ctx, jobId).Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Status: %s\n", *taskResponse.Status)
if taskResponse.Output != nil && taskResponse.Output.ImageUrls != nil {
fmt.Printf("Images: %v\n", taskResponse.Output.ImageUrls)
}
```
## Error Handling
```go
response, httpRes, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
// Check HTTP status code
if httpRes != nil {
fmt.Printf("HTTP Status: %d\n", httpRes.StatusCode)
}
fmt.Printf("Error: %v\n", err)
return
}
```
## Available APIs
- `ImageGenerationAPI` - Text to image, variations, upscaling, editing
- `VideoGenerationAPI` - Video generation and upscaling
- `VideoAPI` - Task status checking
- `AccountManagementAPI` - Account balance and information
---
# Image Generation
_Image generation API reference for Go SDK_
## GenerateImage()
Create a new text-to-image generation task.
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Create image generation request
text := "a serene mountain landscape at sunset"
callback := "https://your-domain.com/webhook"
request := legnext.DiffusionRequest{
Text: &text,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Job ID: %s\n", *response.JobId)
fmt.Printf("Status: %s\n", *response.Status)
}
```
**Parameters:**
- `Text` (string): Text prompt (1-8192 characters)
- `Callback` (string, optional): Webhook URL for completion notification
**Returns:** Response with `JobId` and `Status`
---
## VaryImage()
Create variations of a generated image.
```go
jobId := "original-job-id"
imageNo := int32(0)
varyType := int32(1) // 0=Subtle, 1=Strong
remixPrompt := "add more clouds"
callback := "https://your-domain.com/webhook"
request := legnext.VaryRequest{
JobId: &jobId,
ImageNo: &imageNo,
Type: &varyType,
RemixPrompt: &remixPrompt,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.VaryImage(ctx).
VaryRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Variation Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `Type` (int32): Variation type (0=Subtle, 1=Strong)
- `RemixPrompt` (string, optional): Additional prompt for variation
- `Callback` (string, optional): Webhook URL
---
## RemixImage()
Transform an image with a new prompt.
```go
jobId := "original-job-id"
imageNo := int32(0)
remixPrompt := "transform into a dramatic storm scene"
mode := int32(0) // 0=Strong, 1=Subtle
callback := "https://your-domain.com/webhook"
request := legnext.RemixRequest{
JobId: &jobId,
ImageNo: &imageNo,
RemixPrompt: &remixPrompt,
Mode: &mode,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.RemixImage(ctx).
RemixRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Remix Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `RemixPrompt` (string): New prompt to apply to the image
- `Mode` (int32): Remix intensity (0=Strong, 1=Subtle)
- `Callback` (string, optional): Webhook URL
---
## UpscaleImage()
Upscale a generated image to higher resolution.
```go
jobId := "original-job-id"
imageNo := int32(0)
upscaleType := int32(1) // 0=Subtle, 1=Creative
callback := "https://your-domain.com/webhook"
request := legnext.UpscaleRequest{
JobId: &jobId,
ImageNo: &imageNo,
Type: &upscaleType,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.UpscaleImage(ctx).
UpscaleRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Upscale Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `Type` (int32): Upscale type (0=Subtle, 1=Creative)
- `Callback` (string, optional): Webhook URL
---
## RerollImage()
Regenerate with the same prompt.
```go
jobId := "original-job-id"
callback := "https://your-domain.com/webhook"
request := legnext.RerollRequest{
JobId: &jobId,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.RerollImage(ctx).
RerollRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Reroll Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `Callback` (string, optional): Webhook URL
---
## BlendImages()
Blend 2-5 images together.
```go
imageUrls := []string{
"https://example.com/image1.png",
"https://example.com/image2.png",
}
aspectRatio := "1:1" // Options: 1:1, 16:9, 9:16, 3:2, 2:3
callback := "https://your-domain.com/webhook"
request := legnext.BlendRequest{
ImgUrls: imageUrls,
AspectRatio: &aspectRatio,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.BlendImages(ctx).
BlendRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Blend Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `ImgUrls` ([]string): Array of 2-5 image URLs
- `AspectRatio` (string, optional): Output aspect ratio (1:1, 16:9, 9:16, 3:2, 2:3)
- `Callback` (string, optional): Webhook URL
---
## DescribeImage()
Generate text descriptions from an image.
```go
imgUrl := "https://example.com/image.png"
callback := "https://your-domain.com/webhook"
request := legnext.DescribeRequest{
ImgUrl: &imgUrl,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.DescribeImage(ctx).
DescribeRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Describe Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `ImgUrl` (string): URL of the image to describe
- `Callback` (string, optional): Webhook URL
---
## EditImage()
Edit an image with text description.
```go
jobId := "original-job-id"
imageNo := int32(0)
canvas := "1:1" // Canvas size
imgPos := int32(0) // Image position
remixPrompt := "change the sky to sunset colors"
callback := "https://your-domain.com/webhook"
request := legnext.EditRequest{
JobId: &jobId,
ImageNo: &imageNo,
Canvas: &canvas,
ImgPos: &imgPos,
RemixPrompt: &remixPrompt,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.EditImage(ctx).
EditRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Edit Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `Canvas` (string): Canvas size (e.g., "1:1")
- `ImgPos` (int32): Image position
- `RemixPrompt` (string): Edit instructions
- `Callback` (string, optional): Webhook URL
---
## InpaintImage()
Fill masked regions in an image.
```go
jobId := "original-job-id"
imageNo := int32(0)
remixPrompt := "fill with forest landscape"
mask := "mask-url-or-coordinates"
callback := "https://your-domain.com/webhook"
request := legnext.InpaintRequest{
JobId: &jobId,
ImageNo: &imageNo,
RemixPrompt: &remixPrompt,
Mask: &mask,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.InpaintImage(ctx).
InpaintRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Inpaint Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `RemixPrompt` (string): Inpainting prompt
- `Mask` (string): Mask data or coordinates
- `Callback` (string, optional): Webhook URL
---
## OutpaintImage()
Extend image boundaries.
```go
jobId := "original-job-id"
imageNo := int32(0)
scale := float32(1.5) // Scale factor (1.1-3.0)
remixPrompt := "extend with matching scenery"
callback := "https://your-domain.com/webhook"
request := legnext.OutpaintRequest{
JobId: &jobId,
ImageNo: &imageNo,
Scale: &scale,
RemixPrompt: &remixPrompt,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.OutpaintImage(ctx).
OutpaintRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Outpaint Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `Scale` (float32): Scale factor (1.1-3.0)
- `RemixPrompt` (string, optional): Outpainting prompt
- `Callback` (string, optional): Webhook URL
---
## PanImage()
Create panoramic or panned views.
```go
jobId := "original-job-id"
imageNo := int32(0)
direction := int32(1) // 0=Down, 1=Right, 2=Up, 3=Left
scale := float32(1.5) // Scale factor (1.1-3.0)
remixPrompt := "pan to the right with continuous scenery"
callback := "https://your-domain.com/webhook"
request := legnext.PanRequest{
JobId: &jobId,
ImageNo: &imageNo,
Direction: &direction,
Scale: &scale,
RemixPrompt: &remixPrompt,
Callback: &callback,
}
response, httpRes, err := client.ImageGenerationAPI.PanImage(ctx).
PanRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Pan Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original image job ID
- `ImageNo` (int32): Image index (0-3)
- `Direction` (int32): Pan direction (0=Down, 1=Right, 2=Up, 3=Left)
- `Scale` (float32): Scale factor (1.1-3.0)
- `RemixPrompt` (string, optional): Panning prompt
- `Callback` (string, optional): Webhook URL
---
## ShortenPrompt()
Optimize and simplify prompts.
```go
prompt := "your very long and detailed prompt here with lots of unnecessary words and descriptions that could be made more concise..."
request := legnext.ShortenRequest{
Prompt: &prompt,
}
response, httpRes, err := client.ImageGenerationAPI.ShortenPrompt(ctx).
ShortenRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Shortened prompt: %s\n", *response.ShortenedPrompt)
```
**Parameters:**
- `Prompt` (string): Long prompt to optimize
**Returns:** Response with `ShortenedPrompt`
---
## Complete Example
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
// Configure API client
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Step 1: Generate image
text := "a beautiful sunset over mountains"
callback := "https://your-domain.com/webhook"
request := legnext.DiffusionRequest{
Text: &text,
Callback: &callback,
}
response, _, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
jobId := *response.JobId
fmt.Printf("Image generation started: %s\n", jobId)
// Step 2: Wait for completion (see Task Management docs)
// ...
// Step 3: Upscale the first image
imageNo := int32(0)
upscaleType := int32(1)
upscaleRequest := legnext.UpscaleRequest{
JobId: &jobId,
ImageNo: &imageNo,
Type: &upscaleType,
}
upscaleResponse, _, err := client.ImageGenerationAPI.UpscaleImage(ctx).
UpscaleRequest(upscaleRequest).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Upscale started: %s\n", *upscaleResponse.JobId)
}
```
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/go/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/go/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/go/quickstart)
---
# Video Generation
_Video generation API reference for Go SDK_
## GenerateVideo()
Generate a video from text prompt, image URL, or existing generated image.
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Option 1: Generate from text only
prompt := "a flowing river through mountains"
videoType := int32(1) // 0=480p, 1=720p
callback := "https://your-domain.com/webhook"
request := legnext.VideoDiffusionRequest{
Prompt: &prompt,
VideoType: &videoType,
Callback: &callback,
}
response, httpRes, err := client.VideoGenerationAPI.GenerateVideo(ctx).
VideoDiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Job ID: %s\n", *response.JobId)
fmt.Printf("Status: %s\n", *response.Status)
}
```
**Option 2: Generate from Image URL:**
```go
// Generate from image URL
prompt := "https://example.com/image.png a flowing river through mountains"
videoType := int32(1)
callback := "https://your-domain.com/webhook"
request := legnext.VideoDiffusionRequest{
Prompt: &prompt,
VideoType: &videoType,
Callback: &callback,
}
response, httpRes, err := client.VideoGenerationAPI.GenerateVideo(ctx).
VideoDiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Job ID: %s\n", *response.JobId)
```
**Option 3: Animate Generated Image:**
```go
// Animate from previously generated image
originalJobId := "image-generation-job-id"
imageNo := int32(0)
videoType := int32(1)
callback := "https://your-domain.com/webhook"
request := legnext.VideoDiffusionRequest{
JobId: &originalJobId,
ImageNo: &imageNo,
VideoType: &videoType,
Callback: &callback,
}
response, httpRes, err := client.VideoGenerationAPI.GenerateVideo(ctx).
VideoDiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `Prompt` (string, conditional): Video prompt or "[image_url] prompt text" (1-8192 characters) - required for text/URL mode
- `JobId` (string, conditional): Original image generation job ID - required for image animation mode
- `ImageNo` (int32, conditional): Image index (0-3) - required when using JobId
- `VideoType` (int32, optional): Quality (0=480p, 1=720p)
- `Callback` (string, optional): Webhook URL
**Returns:** Response with `JobId` and `Status`
---
## ExtendVideo()
Extend an existing video.
```go
jobId := "original-video-job-id"
videoNo := int32(0)
prompt := "continue with dramatic lighting"
callback := "https://your-domain.com/webhook"
request := legnext.ExtendVideoRequest{
JobId: &jobId,
VideoNo: &videoNo,
Prompt: &prompt,
Callback: &callback,
}
response, httpRes, err := client.VideoGenerationAPI.ExtendVideo(ctx).
ExtendVideoRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Extension Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original video task ID
- `VideoNo` (int32): Video index (0-3)
- `Prompt` (string, optional): Extension prompt (1-8192 characters)
- `Callback` (string, optional): Webhook URL
**Returns:** Response with `JobId` and `Status`
---
## UpscaleVideo()
Upscale video to higher resolution.
```go
jobId := "original-video-job-id"
videoNo := int32(0)
callback := "https://your-domain.com/webhook"
request := legnext.VideoUpscaleRequest{
JobId: &jobId,
VideoNo: &videoNo,
Callback: &callback,
}
response, httpRes, err := client.VideoGenerationAPI.UpscaleVideo(ctx).
VideoUpscaleRequest(request).
Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Upscale Job ID: %s\n", *response.JobId)
```
**Parameters:**
- `JobId` (string): Original video task ID
- `VideoNo` (int32): Video index (0-3)
- `Callback` (string, optional): Webhook URL
**Returns:** Response with `JobId` and `Status`
---
## Complete Example
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
// Configure API client
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
if apiKey == "" {
fmt.Println("LEGNEXT_API_KEY environment variable not set")
return
}
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Step 1: Generate video
prompt := "a beautiful sunset over the ocean"
videoType := int32(1)
request := legnext.VideoDiffusionRequest{
Prompt: &prompt,
VideoType: &videoType,
}
response, _, err := client.VideoGenerationAPI.GenerateVideo(ctx).
VideoDiffusionRequest(request).
Execute()
if err != nil {
fmt.Printf("Error generating video: %v\n", err)
return
}
jobId := *response.JobId
fmt.Printf("Video generation started: %s\n", jobId)
// Step 2: Wait for completion (see Task Management docs)
// ...
// Step 3: Extend the video
videoNo := int32(0)
extendPrompt := "continue with dramatic clouds"
extendRequest := legnext.ExtendVideoRequest{
JobId: &jobId,
VideoNo: &videoNo,
Prompt: &extendPrompt,
}
extendResponse, _, err := client.VideoGenerationAPI.ExtendVideo(ctx).
ExtendVideoRequest(extendRequest).
Execute()
if err != nil {
fmt.Printf("Error extending video: %v\n", err)
return
}
fmt.Printf("Video extension started: %s\n", *extendResponse.JobId)
// Step 4: Upscale the extended video
upscaleRequest := legnext.VideoUpscaleRequest{
JobId: extendResponse.JobId,
VideoNo: &videoNo,
}
upscaleResponse, _, err := client.VideoGenerationAPI.UpscaleVideo(ctx).
VideoUpscaleRequest(upscaleRequest).
Execute()
if err != nil {
fmt.Printf("Error upscaling video: %v\n", err)
return
}
fmt.Printf("Video upscale started: %s\n", *upscaleResponse.JobId)
}
```
---
## Error Handling
```go
response, httpRes, err := client.VideoGenerationAPI.GenerateVideo(ctx).
VideoDiffusionRequest(request).
Execute()
if err != nil {
if httpRes != nil {
switch httpRes.StatusCode {
case 400:
fmt.Println("Validation error: Check request parameters")
case 401:
fmt.Println("Authentication error: Invalid API key")
case 404:
fmt.Println("Resource not found")
case 429:
fmt.Println("Rate limit exceeded. Please retry later.")
case 500, 502, 503:
fmt.Println("Server error. Please retry.")
default:
fmt.Printf("API error (%d): %v\n", httpRes.StatusCode, err)
}
} else {
fmt.Printf("Unexpected error: %v\n", err)
}
return
}
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/go/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/go/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/go/quickstart)
---
# Task Management
_Task status, polling, and error handling for Go SDK_
## GetTaskStatus()
Get current task status:
```go
package main
import (
"context"
"fmt"
"os"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func main() {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
jobId := "job-123"
task, httpRes, err := client.TaskManagementAPI.GetTaskStatus(ctx, jobId).Execute()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Status: %s\n", *task.Status)
fmt.Printf("Progress: %d%%\n", *task.Progress)
if *task.Status == "completed" {
fmt.Printf("Result: %v\n", task.Output)
}
}
```
---
## Polling for Completion
Wait for task completion with polling:
```go
package main
import (
"context"
"fmt"
"os"
"time"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func waitForCompletion(
ctx context.Context,
client *legnext.APIClient,
jobId string,
timeoutSeconds int,
pollIntervalSeconds int,
) (*legnext.TaskResponse, error) {
startTime := time.Now()
timeout := time.Duration(timeoutSeconds) * time.Second
for {
task, _, err := client.TaskManagementAPI.GetTaskStatus(ctx, jobId).Execute()
if err != nil {
return nil, err
}
fmt.Printf("Current status: %s\n", *task.Status)
if *task.Status == "completed" {
fmt.Println("Task completed successfully!")
fmt.Printf("Output: %v\n", task.Output)
return task, nil
} else if *task.Status == "failed" {
return nil, fmt.Errorf("task failed: %v", task.Error)
}
// Check timeout
if time.Since(startTime) > timeout {
return nil, fmt.Errorf("task timeout after %d seconds", timeoutSeconds)
}
// Wait before next poll
time.Sleep(time.Duration(pollIntervalSeconds) * time.Second)
}
}
func main() {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
jobId := "job-123"
result, err := waitForCompletion(ctx, client, jobId, 300, 3)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Final result: %v\n", result)
}
```
---
## Complete Example with Error Handling
```go
package main
import (
"context"
"fmt"
"os"
"time"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func waitForCompletion(
ctx context.Context,
client *legnext.APIClient,
jobId string,
timeoutSeconds int,
pollIntervalSeconds int,
) (*legnext.TaskResponse, error) {
startTime := time.Now()
timeout := time.Duration(timeoutSeconds) * time.Second
for {
task, _, err := client.TaskManagementAPI.GetTaskStatus(ctx, jobId).Execute()
if err != nil {
return nil, err
}
if *task.Status == "completed" {
return task, nil
} else if *task.Status == "failed" {
return nil, fmt.Errorf("task failed: %v", task.Error)
}
if time.Since(startTime) > timeout {
return nil, fmt.Errorf("task timeout after %d seconds", timeoutSeconds)
}
time.Sleep(time.Duration(pollIntervalSeconds) * time.Second)
}
}
func generateImageWithPolling() error {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
// Step 1: Start generation
text := "a beautiful sunset over mountains"
request := legnext.DiffusionRequest{
Text: &text,
}
response, _, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
return fmt.Errorf("error starting generation: %v", err)
}
jobId := *response.JobId
fmt.Printf("Job started: %s\n", jobId)
// Step 2: Poll for completion
result, err := waitForCompletion(ctx, client, jobId, 600, 3)
if err != nil {
return fmt.Errorf("error waiting for completion: %v", err)
}
// Step 3: Get final result
if result.Output != nil && result.Output.ImageUrls != nil {
fmt.Printf("Image URLs: %v\n", result.Output.ImageUrls)
}
return nil
}
func main() {
if err := generateImageWithPolling(); err != nil {
fmt.Printf("Error: %v\n", err)
}
}
```
---
## Error Handling
**HTTP Error Handling:**
```go
task, httpRes, err := client.TaskManagementAPI.GetTaskStatus(ctx, jobId).Execute()
if err != nil {
if httpRes != nil {
switch httpRes.StatusCode {
case 400:
fmt.Println("Validation error: Check request parameters")
case 401:
fmt.Println("Authentication error: Invalid API key")
case 404:
fmt.Println("Resource not found: Check job ID exists")
case 429:
fmt.Println("Rate limit exceeded. Please retry later.")
case 500, 502, 503:
fmt.Println("Server error. Please retry with backoff.")
default:
fmt.Printf("API error (%d): %v\n", httpRes.StatusCode, err)
}
} else {
fmt.Printf("Unexpected error: %v\n", err)
}
return
}
```
**Common HTTP Status Codes:**
| Status Code | Description | Action |
|-------------|-------------|--------|
| 400 | Invalid request parameters | Check request body format |
| 401 | Invalid API key | Verify API key is correct |
| 404 | Resource not found | Check job ID exists |
| 429 | Rate limit exceeded | Wait and retry with backoff |
| 500/502/503 | Server error | Retry with exponential backoff |
**Retry Logic with Exponential Backoff:**
```go
import (
"math"
"time"
)
func callWithRetry(
ctx context.Context,
client *legnext.APIClient,
request legnext.DiffusionRequest,
maxRetries int,
) (*legnext.TaskResponse, error) {
for i := 0; i < maxRetries; i++ {
response, httpRes, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
if httpRes != nil {
if httpRes.StatusCode == 429 {
// Rate limited - wait and retry
time.Sleep(5 * time.Second)
continue
} else if httpRes.StatusCode >= 500 {
// Server error - exponential backoff
delay := time.Duration(math.Pow(2, float64(i))) * time.Second
time.Sleep(delay)
if i == maxRetries-1 {
return nil, err
}
continue
} else {
// Other errors - don't retry
return nil, err
}
}
return nil, err
}
return response, nil
}
return nil, fmt.Errorf("max retries exceeded")
}
// Usage
text := "a beautiful landscape"
request := legnext.DiffusionRequest{
Text: &text,
}
response, err := callWithRetry(ctx, client, request, 3)
if err != nil {
fmt.Printf("Failed after retries: %v\n", err)
return
}
```
---
## Concurrent Operations with Goroutines
For processing multiple tasks concurrently:
```go
package main
import (
"context"
"fmt"
"os"
"sync"
legnext "github.com/legnext-ai/sdks/sdks/go"
)
func generateMultipleImages() error {
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
ctx := context.Background()
prompts := []string{"sunset", "mountains", "ocean"}
var wg sync.WaitGroup
results := make(chan string, len(prompts))
errors := make(chan error, len(prompts))
for _, prompt := range prompts {
wg.Add(1)
go func(p string) {
defer wg.Done()
// Start generation
text := p
request := legnext.DiffusionRequest{
Text: &text,
}
response, _, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
errors <- err
return
}
jobId := *response.JobId
// Wait for completion
result, err := waitForCompletion(ctx, client, jobId, 600, 3)
if err != nil {
errors <- err
return
}
if result.Output != nil && result.Output.ImageUrls != nil && len(result.Output.ImageUrls) > 0 {
results <- result.Output.ImageUrls[0]
}
}(prompt)
}
// Wait for all goroutines
go func() {
wg.Wait()
close(results)
close(errors)
}()
// Collect results
for {
select {
case url, ok := <-results:
if ok {
fmt.Printf("Image generated: %s\n", url)
}
case err, ok := <-errors:
if ok {
fmt.Printf("Error: %v\n", err)
}
}
if len(results) == 0 && len(errors) == 0 {
break
}
}
return nil
}
func main() {
if err := generateMultipleImages(); err != nil {
fmt.Printf("Error: %v\n", err)
}
}
```
---
## Progress Callbacks
```go
type ProgressCallback func(progress int, status string)
func waitForCompletionWithProgress(
ctx context.Context,
client *legnext.APIClient,
jobId string,
onProgress ProgressCallback,
timeoutSeconds int,
pollIntervalSeconds int,
) (*legnext.TaskResponse, error) {
startTime := time.Now()
timeout := time.Duration(timeoutSeconds) * time.Second
for {
task, _, err := client.TaskManagementAPI.GetTaskStatus(ctx, jobId).Execute()
if err != nil {
return nil, err
}
// Call progress callback
if onProgress != nil {
progress := 0
if task.Progress != nil {
progress = int(*task.Progress)
}
status := ""
if task.Status != nil {
status = *task.Status
}
onProgress(progress, status)
}
if *task.Status == "completed" {
return task, nil
} else if *task.Status == "failed" {
return nil, fmt.Errorf("task failed: %v", task.Error)
}
if time.Since(startTime) > timeout {
return nil, fmt.Errorf("task timeout after %d seconds", timeoutSeconds)
}
time.Sleep(time.Duration(pollIntervalSeconds) * time.Second)
}
}
// Usage
result, err := waitForCompletionWithProgress(
ctx,
client,
jobId,
func(progress int, status string) {
fmt.Printf("Progress: %d%% - Status: %s\n", progress, status)
},
600,
3,
)
```
---
## Context with Timeout
Use Go's context for better timeout management:
```go
import (
"context"
"time"
)
func main() {
// Create context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
config := legnext.NewConfiguration()
config.Servers = legnext.ServerConfigurations{
{
URL: "https://api.legnext.ai",
},
}
apiKey := os.Getenv("LEGNEXT_API_KEY")
config.AddDefaultHeader("x-api-key", apiKey)
client := legnext.NewAPIClient(config)
// Start generation
text := "a beautiful landscape"
request := legnext.DiffusionRequest{
Text: &text,
}
response, _, err := client.ImageGenerationAPI.GenerateImage(ctx).
DiffusionRequest(request).
Execute()
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
fmt.Println("Request timeout exceeded")
} else {
fmt.Printf("Error: %v\n", err)
}
return
}
fmt.Printf("Job ID: %s\n", *response.JobId)
}
```
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/go/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/go/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/go/quickstart)
---
# Installation
_Install the Legnext Java SDK_
## Requirements
- **Java**: Version 1.8 or higher
- **Build Tool**: Maven 3.8.3+ or Gradle 7.2+
## Maven Installation
Add this dependency to your project's `pom.xml`:
```xml
com.legnext
legnext-sdk
1.0.0
```
## Gradle Installation
Add this dependency to your `build.gradle`:
```groovy
dependencies {
implementation 'com.legnext:legnext-sdk:1.0.0'
}
```
## Build from Source
```bash
git clone https://github.com/legnext-ai/legnext-java-sdk.git
cd legnext-java-sdk
mvn clean install
```
## Verify Installation
```bash
mvn dependency:tree | grep legnext
```
---
# Authentication
_Set up authentication for the Legnext Java SDK_
## Get Your API Key
1. Visit [Legnext Dashboard](https://dashboard.legnext.ai)
2. Log in to your account
3. Navigate to **API Keys** section
4. Create a new API key
5. Copy and save it securely
## Using Your API Key
### Method 1: Direct Initialization
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.Configuration;
import org.openapitools.client.api.ImageApi;
public class Example {
public static void main(String[] args) {
ApiClient apiClient = Configuration.getDefaultApiClient();
apiClient.setBasePath("https://api.legnext.ai");
ImageApi imageApi = new ImageApi(apiClient);
String apiKey = "your-api-key-here";
// Use apiKey as parameter in method calls
}
}
```
### Method 2: Environment Variable (Recommended)
Set the environment variable:
```bash
# macOS/Linux
export LEGNEXT_API_KEY="your-api-key-here"
# Windows CMD
set LEGNEXT_API_KEY=your-api-key-here
# Windows PowerShell
$env:LEGNEXT_API_KEY="your-api-key-here"
```
Then in your code:
```java
public class Example {
public static void main(String[] args) {
ApiClient apiClient = Configuration.getDefaultApiClient();
apiClient.setBasePath("https://api.legnext.ai");
String apiKey = System.getenv("LEGNEXT_API_KEY");
ImageApi imageApi = new ImageApi(apiClient);
// Use apiKey as parameter in method calls
}
}
```
### Method 3: Properties File
Create a `config.properties` file:
```properties
legnext.api.key=your-api-key-here
legnext.api.baseurl=https://api.legnext.ai
```
Load it in your code:
```java
import java.io.FileInputStream;
import java.util.Properties;
import org.openapitools.client.ApiClient;
import org.openapitools.client.Configuration;
import org.openapitools.client.api.ImageApi;
public class Example {
public static void main(String[] args) throws Exception {
Properties props = new Properties();
props.load(new FileInputStream("config.properties"));
ApiClient apiClient = Configuration.getDefaultApiClient();
apiClient.setBasePath(props.getProperty("legnext.api.baseurl"));
String apiKey = props.getProperty("legnext.api.key");
ImageApi imageApi = new ImageApi(apiClient);
// Use apiKey as parameter in method calls
}
}
```
## Security Best Practices
⚠️ **Never hardcode API keys in your code**
✅ **Always use environment variables or configuration files**
✅ **Add configuration files to `.gitignore`**
✅ **Rotate keys regularly and revoke compromised ones**
---
## Next Steps
- [Quick Start](https://docs.legnext.ai/sdk/java/quickstart)
- [Image Generation API](https://docs.legnext.ai/sdk/java/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/java/video-generation)
---
# Quick Start
_Get started with the Legnext Java SDK_
## 1. Add Dependency
### Maven
```xml
ai.legnext
legnext-java-sdk
1.0.0
```
### Gradle
```groovy
implementation 'ai.legnext:legnext-java-sdk:1.0.0'
```
## 2. Set API Key
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.ApiException;
import org.openapitools.client.Configuration;
import org.openapitools.client.api.ImageApi;
import java.util.HashMap;
import java.util.Map;
public class QuickStart {
public static void main(String[] args) {
// Configure API client
ApiClient apiClient = Configuration.getDefaultApiClient();
apiClient.setBasePath("https://api.legnext.ai");
String apiKey = System.getenv("LEGNEXT_API_KEY");
// Create API instance
ImageApi api = new ImageApi(apiClient);
try {
// Generate image
Map request = new HashMap<>();
request.put("text", "a beautiful sunset over mountains");
Object response = api.apiV1DiffusionPost(apiKey, request);
System.out.println("Response: " + response);
} catch (ApiException e) {
System.err.println("Error: " + e.getMessage());
System.err.println("Status code: " + e.getCode());
System.err.println("Response body: " + e.getResponseBody());
}
}
}
```
## 4. Check Task Status
```java
import org.openapitools.client.api.VideoApi;
VideoApi taskApi = new VideoApi(apiClient);
String jobId = "your-job-id-here";
try {
Object taskResponse = taskApi.apiV1JobJobIdGet(jobId, apiKey);
System.out.println("Task status: " + taskResponse);
} catch (ApiException e) {
System.err.println("Error: " + e.getMessage());
}
```
## Error Handling
```java
try {
Object response = api.apiV1DiffusionPost(apiKey, request);
} catch (ApiException e) {
// HTTP status code
System.err.println("Status code: " + e.getCode());
// Error message
System.err.println("Message: " + e.getMessage());
// Response body
System.err.println("Response: " + e.getResponseBody());
// Response headers
System.err.println("Headers: " + e.getResponseHeaders());
}
```
## Available APIs
- `ImageApi` - Text to image, variations, upscaling, editing
- `VideoApi` - Video generation, upscaling, and task status
- `AccountManagementApi` - Account balance and information
---
# Image Generation
_Image generation API reference for Java SDK_
## apiV1DiffusionPost()
Create a new text-to-image generation task.
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.ImageApi;
import org.openapitools.client.ApiException;
import java.util.HashMap;
import java.util.Map;
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("https://api.legnext.ai");
ImageApi imageApi = new ImageApi(apiClient);
String apiKey = "your-api-key-here";
// Create request body
Map body = new HashMap<>();
body.put("text", "a serene mountain landscape at sunset");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1DiffusionPost(apiKey, body);
System.out.println("Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `xApiKey` (String): Your API key
- `body` (Object): Request body with:
- `text` (String): Text prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## apiV1VaryPost()
Create variations of a generated image.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("imageNo", 0);
body.put("type", 1); // 0=Subtle, 1=Strong
body.put("remixPrompt", "add more clouds"); // Optional
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1VaryPost(apiKey, body);
System.out.println("Variation Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `imageNo` (Integer): Image index (0-3)
- `type` (Integer): Variation intensity (0=Subtle, 1=Strong)
- `remixPrompt` (String, optional): Additional guidance
- `callback` (String, optional): Webhook URL
---
## apiV1UpscalePost()
Upscale a generated image.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("imageNo", 0);
body.put("type", 1); // 0=Subtle, 1=Creative
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1UpscalePost(apiKey, body);
System.out.println("Upscale Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `imageNo` (Integer): Image index (0-3)
- `type` (Integer): Upscaling type (0=Subtle, 1=Creative)
- `callback` (String, optional): Webhook URL
---
## apiV1RerollPost()
Regenerate with the same prompt.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1RerollPost(apiKey, body);
System.out.println("Reroll Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `callback` (String, optional): Webhook URL
---
## apiV1BlendPost()
Blend 2-5 images together.
```java
import java.util.Arrays;
import java.util.List;
Map body = new HashMap<>();
List imageUrls = Arrays.asList(
"https://example.com/image1.png",
"https://example.com/image2.png"
);
body.put("imgUrls", imageUrls);
body.put("aspect_ratio", "1:1"); // "2:3", "1:1", or "3:2"
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1BlendPost(apiKey, body);
System.out.println("Blend Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `imgUrls` (List): 2-5 image URLs
- `aspect_ratio` (String): Output ratio ("2:3", "1:1", or "3:2")
- `callback` (String, optional): Webhook URL
---
## apiV1DescribePost()
Generate text descriptions from an image.
```java
Map body = new HashMap<>();
body.put("imgUrl", "https://example.com/image.png");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1DescribePost(apiKey, body);
System.out.println("Description: " + response.getDescription());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `imgUrl` (String): Image URL
- `callback` (String, optional): Webhook URL
---
## apiV1EditPost()
Edit an image with text description.
```java
Map body = new HashMap<>();
body.put("canvas", "original-job-id");
body.put("imgPos", 0); // Image index
body.put("remixPrompt", "change the sky to sunset colors");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1EditPost(apiKey, body);
System.out.println("Edit Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `canvas` (String): Original image task ID
- `imgPos` (Integer): Image index
- `remixPrompt` (String): Edit instruction
- `callback` (String, optional): Webhook URL
---
## apiV1InpaintPost()
Fill masked regions in an image.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("imageNo", 0);
body.put("remixPrompt", "fill with forest landscape");
body.put("mask", "mask-url-or-coordinates");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1InpaintPost(apiKey, body);
System.out.println("Inpaint Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `imageNo` (Integer): Image index
- `remixPrompt` (String): Fill instruction
- `mask` (String): Mask URL or coordinates
- `callback` (String, optional): Webhook URL
---
## apiV1OutpaintPost()
Extend image boundaries.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("imageNo", 0);
body.put("scale", 1.5); // 1.1 to 3.0
body.put("remixPrompt", "extend with more sky"); // Optional
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1OutpaintPost(apiKey, body);
System.out.println("Outpaint Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `imageNo` (Integer): Image index
- `scale` (Double): Scale factor (1.1-3.0)
- `remixPrompt` (String, optional): Extension guidance
- `callback` (String, optional): Webhook URL
---
## apiV1PanPost()
Create panoramic or panned views.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("imageNo", 0);
body.put("direction", 3); // 0=Down, 1=Right, 2=Up, 3=Left
body.put("scale", 1.5); // 1.1 to 3.0
body.put("remixPrompt", "add dramatic lighting"); // Optional
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1PanPost(apiKey, body);
System.out.println("Pan Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `imageNo` (Integer): Image index
- `direction` (Integer): Pan direction (0=Down, 1=Right, 2=Up, 3=Left)
- `scale` (Double): Scale factor (1.1-3.0)
- `remixPrompt` (String, optional): Pan guidance
- `callback` (String, optional): Webhook URL
---
## apiV1RemixPost()
Remix an image with different prompt guidance.
```java
Map body = new HashMap<>();
body.put("jobId", "original-job-id");
body.put("imageNo", 0);
body.put("mode", 0); // 0=Strong, 1=Subtle
body.put("remixPrompt", "change to a winter scene");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1RemixPost(apiKey, body);
System.out.println("Remix Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original image task ID
- `imageNo` (Integer): Image index
- `mode` (Integer): Remix intensity (0=Strong, 1=Subtle)
- `remixPrompt` (String): Remix instruction
- `callback` (String, optional): Webhook URL
---
## apiV1ShortenPost()
Optimize and simplify prompts.
```java
Map body = new HashMap<>();
body.put("prompt", "your very long and detailed prompt here...");
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = imageApi.apiV1ShortenPost(apiKey, body);
System.out.println("Optimized prompt: " + response.getShortenedPrompt());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `prompt` (String): Prompt to optimize
- `callback` (String, optional): Webhook URL
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/java/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/java/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/java/quickstart)
---
# Video Generation
_Video generation API reference for Java SDK_
## apiV1VideoDiffusionPost()
Generate a video from text prompt.
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.VideoApi;
import org.openapitools.client.ApiException;
import java.util.HashMap;
import java.util.Map;
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("https://api.legnext.ai");
VideoApi videoApi = new VideoApi(apiClient);
String apiKey = "your-api-key-here";
// Text-to-video
Map body = new HashMap<>();
body.put("prompt", "a flowing river through mountains");
body.put("videoType", 1); // Optional: 0=480p, 1=720p
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = videoApi.apiV1VideoDiffusionPost(apiKey, body);
System.out.println("Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Image-to-video animation (using jobId + imageNo):**
```java
// Animate an existing generated image
Map body = new HashMap<>();
body.put("jobId", "original-image-job-id");
body.put("imageNo", 0); // Image index from original generation
body.put("videoType", 1);
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = videoApi.apiV1VideoDiffusionPost(apiKey, body);
System.out.println("Video Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Image-to-video animation (using image URL in prompt):**
```java
// Animate an image using URL in prompt
Map body = new HashMap<>();
body.put("prompt", "https://example.com/image.png a flowing river through mountains");
body.put("videoType", 1);
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = videoApi.apiV1VideoDiffusionPost(apiKey, body);
System.out.println("Video Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- Text-only mode:
- `prompt` (String): Video prompt (1-8192 characters)
- `videoType` (Integer, optional): Quality (0=480p, 1=720p)
- `callback` (String, optional): Webhook URL
- jobId + imageNo mode:
- `jobId` (String): Image generation task ID
- `imageNo` (Integer): Image index (0-3)
- `videoType` (Integer, optional): Quality (0=480p, 1=720p)
- `callback` (String, optional): Webhook URL
- Image URL in prompt mode:
- `prompt` (String): "[image_url] prompt text" format (1-8192 characters)
- `videoType` (Integer, optional): Quality (0=480p, 1=720p)
- `callback` (String, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## apiV1ExtendVideoPost()
Extend an existing video.
```java
Map body = new HashMap<>();
body.put("jobId", "original-video-job-id");
body.put("videoNo", 0); // 0-3
body.put("prompt", "continue with dramatic lighting"); // Optional
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = videoApi.apiV1ExtendVideoPost(apiKey, body);
System.out.println("Extended video Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original video task ID
- `videoNo` (Integer): Video index (0-3)
- `prompt` (String, optional): Extension prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL
---
## apiV1VideoUpscalePost()
Upscale video to higher resolution.
```java
Map body = new HashMap<>();
body.put("jobId", "original-video-job-id");
body.put("videoNo", 0); // 0-3
body.put("callback", "https://your-domain.com/webhook"); // Optional
try {
var response = videoApi.apiV1VideoUpscalePost(apiKey, body);
System.out.println("Upscaled video Job ID: " + response.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
**Parameters:**
- `jobId` (String): Original video task ID
- `videoNo` (Integer): Video index (0-3)
- `callback` (String, optional): Webhook URL
---
## Complete Example
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.VideoApi;
import org.openapitools.client.ApiException;
import java.util.HashMap;
import java.util.Map;
public class VideoGenerationExample {
public static void main(String[] args) {
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("https://api.legnext.ai");
VideoApi videoApi = new VideoApi(apiClient);
String apiKey = System.getenv("LEGNEXT_API_KEY");
try {
// Step 1: Generate initial video
Map body = new HashMap<>();
body.put("prompt", "a sunset over ocean waves");
body.put("videoType", 1);
var initialResponse = videoApi.apiV1VideoDiffusionPost(apiKey, body);
String jobId = initialResponse.getJobId();
System.out.println("Initial video job: " + jobId);
// Wait for completion (see task-management.mdx)
// ...
// Step 2: Extend the video
Map extendBody = new HashMap<>();
extendBody.put("jobId", jobId);
extendBody.put("videoNo", 0);
extendBody.put("prompt", "zoom in on the waves");
var extendResponse = videoApi.apiV1ExtendVideoPost(apiKey, extendBody);
System.out.println("Extended video job: " + extendResponse.getJobId());
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
e.printStackTrace();
}
}
}
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/java/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/java/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/java/quickstart)
---
# Task Management
_Task status, polling, and error handling for Java SDK_
## apiV1JobJobIdGet()
Get current task status:
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.VideoApi;
import org.openapitools.client.ApiException;
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("https://api.legnext.ai");
VideoApi videoApi = new VideoApi(apiClient);
String apiKey = "your-api-key-here";
String jobId = "job-123";
try {
var task = videoApi.apiV1JobJobIdGet(jobId, apiKey);
System.out.println("Status: " + task.getStatus());
System.out.println("Progress: " + task.getProgress() + "%");
if ("completed".equals(task.getStatus())) {
System.out.println("Result: " + task.getOutput());
}
} catch (ApiException e) {
System.err.println("Error: " + e.getResponseBody());
}
```
---
## Polling for Completion
Wait for task completion with polling:
```java
public class TaskPoller {
public static void waitForCompletion(
VideoApi api,
String jobId,
String apiKey,
int timeoutSeconds,
int pollIntervalSeconds
) throws ApiException, InterruptedException {
long startTime = System.currentTimeMillis();
long timeout = timeoutSeconds * 1000;
while (true) {
var task = api.apiV1JobJobIdGet(jobId, apiKey);
String status = task.getStatus();
System.out.println("Current status: " + status);
if ("completed".equals(status)) {
System.out.println("Task completed successfully!");
System.out.println("Output: " + task.getOutput());
return;
} else if ("failed".equals(status)) {
throw new RuntimeException("Task failed: " + task.getError());
}
// Check timeout
if (System.currentTimeMillis() - startTime > timeout) {
throw new RuntimeException("Task timeout after " + timeoutSeconds + " seconds");
}
// Wait before next poll
Thread.sleep(pollIntervalSeconds * 1000);
}
}
}
```
**Usage:**
```java
try {
TaskPoller.waitForCompletion(imageApi, jobId, apiKey, 300, 3);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
```
---
## Complete Example with Error Handling
```java
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.VideoApi;
import org.openapitools.client.ApiException;
import java.util.HashMap;
import java.util.Map;
public class ImageGenerationWithPolling {
public static void main(String[] args) {
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("https://api.legnext.ai");
VideoApi videoApi = new VideoApi(apiClient);
String apiKey = System.getenv("LEGNEXT_API_KEY");
try {
// Step 1: Start generation
Map body = new HashMap<>();
body.put("text", "a beautiful sunset over mountains");
var response = imageApi.apiV1DiffusionPost(apiKey, body);
String jobId = response.getJobId();
System.out.println("Job started: " + jobId);
// Step 2: Poll for completion
TaskPoller.waitForCompletion(imageApi, jobId, apiKey, 600, 3);
// Step 3: Get final result
var result = videoApi.apiV1JobJobIdGet(jobId, apiKey);
System.out.println("Image URLs: " + result.getOutput().getImageUrls());
} catch (ApiException e) {
handleApiException(e);
} catch (InterruptedException e) {
System.err.println("Polling interrupted: " + e.getMessage());
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
e.printStackTrace();
}
}
private static void handleApiException(ApiException e) {
int statusCode = e.getCode();
String responseBody = e.getResponseBody();
switch (statusCode) {
case 400:
System.err.println("Validation error: " + responseBody);
break;
case 401:
System.err.println("Authentication error: Invalid API key");
break;
case 404:
System.err.println("Resource not found: " + responseBody);
break;
case 429:
System.err.println("Rate limit exceeded. Please retry later.");
break;
case 500:
case 502:
case 503:
System.err.println("Server error: " + responseBody);
break;
default:
System.err.println("API error (" + statusCode + "): " + responseBody);
}
}
}
```
---
## Error Handling
**Common HTTP Status Codes:**
| Status Code | Description | Action |
|-------------|-------------|--------|
| 400 | Invalid request parameters | Check request body format |
| 401 | Invalid API key | Verify API key is correct |
| 404 | Resource not found | Check job ID exists |
| 429 | Rate limit exceeded | Wait and retry with backoff |
| 500/502/503 | Server error | Retry with exponential backoff |
**Handling Different Error Scenarios:**
```java
try {
var response = imageApi.apiV1DiffusionPost(apiKey, body);
} catch (ApiException e) {
if (e.getCode() == 429) {
// Rate limited - implement backoff
Thread.sleep(5000);
// Retry request
} else if (e.getCode() >= 500) {
// Server error - retry with exponential backoff
for (int i = 0; i < 3; i++) {
Thread.sleep((long) Math.pow(2, i) * 1000);
try {
var response = imageApi.apiV1DiffusionPost(apiKey, body);
break; // Success
} catch (ApiException retryEx) {
if (i == 2) throw retryEx; // Last retry failed
}
}
} else {
// Other errors - log and handle
System.err.println("API Error: " + e.getResponseBody());
throw e;
}
}
```
---
## Async Operations with CompletableFuture
For non-blocking operations:
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AsyncExample {
private static final ExecutorService executor = Executors.newFixedThreadPool(5);
public static CompletableFuture generateImageAsync(
VideoApi api,
String apiKey,
String prompt
) {
return CompletableFuture.supplyAsync(() -> {
try {
Map body = new HashMap<>();
body.put("text", prompt);
var response = api.apiV1DiffusionPost(apiKey, body);
String jobId = response.getJobId();
// Poll for completion
TaskPoller.waitForCompletion(api, jobId, apiKey, 600, 3);
var result = api.apiV1JobJobIdGet(jobId, apiKey);
return result.getOutput().getImageUrls().get(0);
} catch (Exception e) {
throw new RuntimeException(e);
}
}, executor);
}
public static void main(String[] args) {
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("https://api.legnext.ai");
VideoApi videoApi = new VideoApi(apiClient);
String apiKey = System.getenv("LEGNEXT_API_KEY");
// Generate multiple images concurrently
CompletableFuture future1 = generateImageAsync(api, apiKey, "sunset");
CompletableFuture future2 = generateImageAsync(api, apiKey, "mountains");
CompletableFuture future3 = generateImageAsync(api, apiKey, "ocean");
CompletableFuture.allOf(future1, future2, future3).join();
try {
System.out.println("Image 1: " + future1.get());
System.out.println("Image 2: " + future2.get());
System.out.println("Image 3: " + future3.get());
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
```
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/java/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/java/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/java/quickstart)
---
# Installation
_Install the Legnext PHP SDK_
## Requirements
- **PHP**: Version 7.4 or higher
- **Composer**: Latest version
## Install via Composer
```bash
composer require legnext-api/php-sdk
```
## Manual Installation
Download the SDK and include it in your project:
```php
```
## Verify Installation
```bash
composer show legnext-api/php-sdk
```
---
# Authentication
_Set up API authentication for PHP SDK_
## Getting Your API Key
1. Visit [Legnext.ai Dashboard](https://legnext.ai/dashboard)
2. Navigate to API Keys section
3. Generate a new API key
4. Copy and store securely
## Authentication Methods
### Method 1: Environment Variables (Recommended)
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key-here"
```
Then use it in your PHP code:
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
// Create API instance
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
// Now you can use the API
// ...
?>
```
### Method 2: Direct Initialization
Hardcode the API key directly (not recommended for production):
```php
setApiKey('x-api-key', 'your-api-key-here');
$config->setHost('https://api.legnext.ai');
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
?>
```
### Method 3: Using vlucas/phpdotenv
Use the `vlucas/phpdotenv` package to load from `.env` files:
```bash
composer require vlucas/phpdotenv
```
```php
load();
// Configure API client
$config = OpenAPI\Client\Configuration::getDefaultConfiguration();
$config->setApiKey('x-api-key', $_ENV['LEGNEXT_API_KEY']);
$config->setHost('https://api.legnext.ai');
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
?>
```
**.env file:**
```
LEGNEXT_API_KEY=your-api-key-here
```
### Method 4: Configuration File
Load API key from a configuration file:
```php
setApiKey('x-api-key', $config_data['api_key']);
$config->setHost('https://api.legnext.ai');
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
?>
```
**config.php:**
```php
'your-api-key-here',
'environment' => 'development',
];
?>
```
### Method 5: Framework Integration (Laravel)
For Laravel applications, use environment variables:
**.env:**
```
LEGNEXT_API_KEY=your-api-key-here
```
**config/legnext.php:**
```php
env('LEGNEXT_API_KEY'),
'host' => env('LEGNEXT_HOST', 'https://api.legnext.ai'),
];
?>
```
**Usage in Laravel:**
```php
setApiKey('x-api-key', config('legnext.api_key'));
$config->setHost(config('legnext.host'));
$this->api = new ImageApi(
new \GuzzleHttp\Client(),
$config
);
}
public function generateImage($text)
{
// Implementation
}
}
?>
```
---
## Complete Configuration Example
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
// Required: API Host
$config->setHost('https://api.legnext.ai');
// Optional: Set debugging mode
$config->setDebug(getenv('LEGNEXT_DEBUG') === 'true');
// Optional: Set timeout (in seconds)
$config->setCurlTimeout(120);
// Optional: Set custom user agent
$config->setUserAgent('MyApp/1.0');
// Optional: SSL verification (recommended: true)
$config->setSSLVerification(true);
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
?>
```
---
## Security Best Practices
1. **Never commit API keys to version control**
```
# .gitignore
.env
config.php
```
2. **Use environment variables in production**
```bash
# Set in your deployment environment
export LEGNEXT_API_KEY="your-production-key"
```
3. **Rotate keys regularly**
- Generate new keys periodically
- Revoke old keys after rotation
4. **Use different keys for development and production**
```php
setApiKey('x-api-key', $apiKey);
?>
```
5. **Restrict API key permissions**
- Use the minimum required permissions
- Monitor usage through the dashboard
6. **Enable SSL verification**
```php
setSSLVerification(true);
?>
```
7. **Protect configuration files**
```php
getenv('LEGNEXT_API_KEY'),
];
?>
```
---
## Testing Authentication
Verify your API key is working:
```php
setApiKey('x-api-key', $apiKey);
$config->setHost('https://api.legnext.ai');
$accountApi = new OpenAPI\Client\Api\AccountManagementApi(
new GuzzleHttp\Client(),
$config
);
try {
// Test with account balance endpoint
$response = $accountApi->apiAccountBalanceGet($apiKey);
echo "✅ Authentication successful!\n";
echo "Balance: " . $response->getBalance() . " credits\n";
} catch (OpenAPI\Client\ApiException $e) {
if ($e->getCode() === 401) {
echo "❌ Authentication failed: Invalid API key\n";
} else {
echo "❌ Error: " . $e->getMessage() . "\n";
}
}
?>
```
---
## Debugging
Enable debugging to see HTTP requests and responses:
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
// Enable debug mode
$config->setDebug(true);
// Set debug file (optional)
$config->setDebugFile('/path/to/debug.log');
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
?>
```
---
## Error Handling
```php
generateImage($request);
} catch (OpenAPI\Client\ApiException $e) {
$statusCode = $e->getCode();
$errorBody = $e->getResponseBody();
switch ($statusCode) {
case 401:
echo "Authentication error: Invalid API key\n";
break;
case 400:
echo "Validation error: " . $errorBody . "\n";
break;
case 404:
echo "Resource not found\n";
break;
case 429:
echo "Rate limit exceeded. Please retry later.\n";
break;
case 500:
case 502:
case 503:
echo "Server error: " . $errorBody . "\n";
break;
default:
echo "API error ({$statusCode}): " . $errorBody . "\n";
}
}
?>
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/php/image-generation)
- [Video Generation](https://docs.legnext.ai/sdk/php/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/php/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/php/quickstart)
---
# Quick Start
_Get started with the Legnext PHP SDK_
## 1. Install
```bash
composer require legnext-api/php-sdk
```
## 2. Set API Key
```php
```
## 3. Basic Example
```php
setHost('https://api.legnext.ai');
$config->setApiKey('x-api-key', $apiKey);
// Create API instance
$api = new OpenAPI\Client\Api\ImageApi(
new GuzzleHttp\Client(),
$config
);
try {
// Generate image
$body = [
'text' => 'a beautiful sunset over mountains'
];
$response = $api->apiV1DiffusionPost($apiKey, $body);
echo "Job ID: " . $response->getJobId() . "\n";
echo "Status: " . $response->getStatus() . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
```
## 4. Check Task Status
```php
apiV1JobJobIdGet($jobId, $apiKey);
echo "Status: " . $taskResponse->getStatus() . "\n";
echo "Task Type: " . $taskResponse->getTaskType() . "\n";
if ($taskResponse->getOutput() !== null) {
$output = $taskResponse->getOutput();
if ($output->getImageUrls() !== null) {
echo "Images:\n";
foreach ($output->getImageUrls() as $url) {
echo " - " . $url . "\n";
}
}
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
```
## Error Handling
```php
apiV1DiffusionPost($apiKey, $body);
} catch (OpenAPI\Client\ApiException $e) {
echo "HTTP Status Code: " . $e->getCode() . "\n";
echo "Error Message: " . $e->getMessage() . "\n";
echo "Response Body: " . $e->getResponseBody() . "\n";
}
?>
```
## Available APIs
- `OpenAPI\Client\Api\ImageApi` - Text to image, variations, upscaling, editing
- `OpenAPI\Client\Api\VideoApi` - Video generation, upscaling, and task status
- `OpenAPI\Client\Api\AccountManagementApi` - Account balance and information
---
# Image Generation
_Image generation API reference for PHP SDK_
## generateImage()
Create a new text-to-image generation task.
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
$api = new ImageGenerationApi(null, $config);
try {
$request = new DiffusionRequest();
$request->setText('a serene mountain landscape at sunset');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->generateImage($request);
echo "Job ID: " . $response->getJobId() . "\n";
echo "Status: " . $response->getStatus() . "\n";
} catch (\OpenAPI\Client\ApiException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
```
**Parameters:**
- `text` (string): Text prompt (1-8192 characters)
- `callback` (string, optional): Webhook URL for completion notification
**Returns:** Response with `job_id` and `status`
---
## varyImage()
Create variations of a generated image.
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setType(1); // 0=Subtle, 1=Strong
$request->setRemixPrompt('add more clouds');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->varyImage($request);
echo "Variation Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `type` (int): Variation type (0=Subtle, 1=Strong)
- `remix_prompt` (string, optional): Additional prompt for variation
- `callback` (string, optional): Webhook URL for completion notification
---
## upscaleImage()
Upscale a generated image to higher resolution.
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setType(1); // 0=Subtle, 1=Creative
$request->setCallback('https://your-domain.com/webhook');
$response = $api->upscaleImage($request);
echo "Upscale Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `type` (int): Upscale type (0=Subtle, 1=Creative)
- `callback` (string, optional): Webhook URL for completion notification
---
## rerollImage()
Regenerate with the same prompt.
```php
setJobId('original-job-id');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->rerollImage($request);
echo "Reroll Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `callback` (string, optional): Webhook URL for completion notification
---
## blendImages()
Blend 2-5 images together.
```php
setImgUrls([
'https://example.com/image1.png',
'https://example.com/image2.png'
]);
$request->setAspectRatio('1:1'); // Options: 1:1, 16:9, 9:16, 3:2, 2:3
$request->setCallback('https://your-domain.com/webhook');
$response = $api->blendImages($request);
echo "Blend Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `img_urls` (array): Array of 2-5 image URLs
- `aspect_ratio` (string, optional): Output aspect ratio (1:1, 16:9, 9:16, 3:2, 2:3)
- `callback` (string, optional): Webhook URL for completion notification
---
## describeImage()
Generate text descriptions from an image.
```php
setImgUrl('https://example.com/image.png');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->describeImage($request);
echo "Describe Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `img_url` (string): URL of the image to describe
- `callback` (string, optional): Webhook URL for completion notification
---
## editImage()
Edit an image with text description.
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setCanvas('full'); // Canvas area: full, object, background
$request->setImgPos('center'); // Image position: center, top, bottom, left, right
$request->setRemixPrompt('change the sky to sunset colors');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->editImage($request);
echo "Edit Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `canvas` (string): Canvas area (full, object, background)
- `img_pos` (string): Image position (center, top, bottom, left, right)
- `remix_prompt` (string): Edit instructions
- `callback` (string, optional): Webhook URL for completion notification
---
## inpaintImage()
Fill masked regions in an image.
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setRemixPrompt('fill with forest landscape');
$request->setMask([
'type' => 'url', // 'url' or 'coordinates'
'value' => 'mask-url'
]);
$request->setCallback('https://your-domain.com/webhook');
$response = $api->inpaintImage($request);
echo "Inpaint Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `remix_prompt` (string): Inpainting prompt
- `mask` (array): Mask object with type ('url' or 'coordinates') and value
- `callback` (string, optional): Webhook URL for completion notification
---
## outpaintImage()
Extend image boundaries.
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setScale(1.5); // Scale factor (1.1-3.0)
$request->setRemixPrompt('extend with natural landscape');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->outpaintImage($request);
echo "Outpaint Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `scale` (float): Expansion scale factor (1.1-3.0)
- `remix_prompt` (string, optional): Outpaint prompt
- `callback` (string, optional): Webhook URL for completion notification
---
## panImage()
Create panoramic or panned views.
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setDirection(1); // 0=Down, 1=Right, 2=Up, 3=Left
$request->setScale(1.5); // Scale factor (1.1-3.0)
$request->setRemixPrompt('continue the landscape');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->panImage($request);
echo "Pan Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `direction` (int): Pan direction (0=Down, 1=Right, 2=Up, 3=Left)
- `scale` (float): Scale factor (1.1-3.0)
- `remix_prompt` (string, optional): Pan prompt
- `callback` (string, optional): Webhook URL for completion notification
---
## remixImage()
Create variations using remix modes (strong or subtle modification).
```php
setJobId('original-job-id');
$request->setImageNo(0);
$request->setMode(0); // 0=Strong, 1=Subtle
$request->setRemixPrompt('change the lighting to blue hour');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->remixImage($request);
echo "Remix Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original image job ID
- `image_no` (int): Image index (0-3)
- `mode` (int): Remix mode (0=Strong, 1=Subtle)
- `remix_prompt` (string, optional): Remix instructions
- `callback` (string, optional): Webhook URL for completion notification
---
## shortenPrompt()
Optimize and simplify prompts.
```php
setPrompt('your very long and detailed prompt here with lots of unnecessary words and descriptions that could be made more concise...');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->shortenPrompt($request);
echo "Shortened prompt: " . $response->getShortenedPrompt() . "\n";
?>
```
**Parameters:**
- `prompt` (string): Long prompt to optimize
- `callback` (string, optional): Webhook URL for completion notification
**Returns:** Response with `shortened_prompt`
---
## Complete Example
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
$api = new ImageGenerationApi(null, $config);
try {
// Step 1: Generate image
$request = new DiffusionRequest();
$request->setText('a beautiful sunset over mountains');
$response = $api->generateImage($request);
$jobId = $response->getJobId();
echo "Image generation started: {$jobId}\n";
// Step 2: Wait for completion (see Task Management docs)
// ...
// Step 3: Upscale the first image
$upscaleRequest = new UpscaleRequest();
$upscaleRequest->setJobId($jobId);
$upscaleRequest->setImageNo(0);
$upscaleRequest->setType(1);
$upscaleResponse = $api->upscaleImage($upscaleRequest);
echo "Upscale started: " . $upscaleResponse->getJobId() . "\n";
} catch (\OpenAPI\Client\ApiException $e) {
echo "HTTP Status: " . $e->getCode() . "\n";
echo "Error Message: " . $e->getMessage() . "\n";
echo "Response Body: " . $e->getResponseBody() . "\n";
}
?>
```
---
## Error Handling
```php
generateImage($request);
} catch (\OpenAPI\Client\ApiException $e) {
$statusCode = $e->getCode();
$errorBody = $e->getResponseBody();
switch ($statusCode) {
case 400:
echo "Validation error: Check request parameters\n";
break;
case 401:
echo "Authentication error: Invalid API key\n";
break;
case 404:
echo "Resource not found\n";
break;
case 429:
echo "Rate limit exceeded. Please retry later.\n";
break;
case 500:
case 502:
case 503:
echo "Server error. Please retry.\n";
break;
default:
echo "API error ({$statusCode}): {$errorBody}\n";
}
}
?>
```
---
## Retry Logic
```php
generateImage($request);
} catch (\OpenAPI\Client\ApiException $e) {
if ($e->getCode() === 429) {
// Rate limited - wait and retry
$retries++;
sleep(5);
continue;
} elseif ($e->getCode() >= 500) {
// Server error - exponential backoff
$retries++;
$delay = pow(2, $retries);
sleep($delay);
if ($retries >= $maxRetries) {
throw $e;
}
continue;
} else {
// Other errors - don't retry
throw $e;
}
}
}
throw new Exception("Max retries exceeded");
}
// Usage
$request = new DiffusionRequest();
$request->setText('a beautiful landscape');
try {
$response = generateWithRetry($api, $request, 3);
echo "Job ID: " . $response->getJobId() . "\n";
} catch (Exception $e) {
echo "Failed after retries: " . $e->getMessage() . "\n";
}
?>
```
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/php/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/php/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/php/quickstart)
---
# Video Generation
_Video generation API reference for PHP SDK_
## generateVideo()
Generate a video from text prompt with optional image URL.
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
$api = new VideoGenerationApi(null, $config);
try {
// Generate from text only
$request = new VideoDiffusionRequest();
$request->setPrompt('a flowing river through mountains');
$request->setVideoType(1); // 0=480p, 1=720p
$request->setCallback('https://your-domain.com/webhook');
$response = $api->generateVideo($request);
echo "Job ID: " . $response->getJobId() . "\n";
echo "Status: " . $response->getStatus() . "\n";
} catch (\OpenAPI\Client\ApiException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
```
**Generate from Image URL in Prompt:**
```php
setPrompt('https://example.com/image.png a flowing river through mountains');
$request->setVideoType(1);
$request->setCallback('https://your-domain.com/webhook');
$response = $api->generateVideo($request);
echo "Job ID: " . $response->getJobId() . "\n";
?>
```
**Generate from Image Animation (using job_id and image_no):**
```php
setJobId('previous-generation-job-id'); // Reference to previous image generation
$request->setImageNo(0); // Image index to animate
$request->setPrompt('continue the flowing motion smoothly');
$request->setVideoType(1);
$request->setCallback('https://your-domain.com/webhook');
$response = $api->generateVideo($request);
echo "Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
*Text-only generation:*
- `prompt` (string): Video prompt (1-8192 characters)
- `video_type` (int, optional): Quality (0=480p, 1=720p)
- `callback` (string, optional): Webhook URL
*Image URL in prompt:*
- `prompt` (string): "[image_url] prompt text" format (1-8192 characters)
- `video_type` (int, optional): Quality (0=480p, 1=720p)
- `callback` (string, optional): Webhook URL
*Image animation:*
- `job_id` (string): Previous image generation job ID
- `image_no` (int): Image index to animate (0-3)
- `prompt` (string, optional): Animation prompt (1-8192 characters)
- `video_type` (int, optional): Quality (0=480p, 1=720p)
- `callback` (string, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## extendVideo()
Extend an existing video.
```php
setJobId('original-video-job-id');
$request->setVideoNo(0);
$request->setPrompt('continue with dramatic lighting');
$request->setCallback('https://your-domain.com/webhook');
$response = $api->extendVideo($request);
echo "Extension Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original video task ID
- `video_no` (int): Video index (0-3)
- `prompt` (string, optional): Extension prompt (1-8192 characters)
- `callback` (string, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## upscaleVideo()
Upscale video to higher resolution.
```php
setJobId('original-video-job-id');
$request->setVideoNo(0);
$request->setCallback('https://your-domain.com/webhook');
$response = $api->upscaleVideo($request);
echo "Upscale Job ID: " . $response->getJobId() . "\n";
?>
```
**Parameters:**
- `job_id` (string): Original video task ID
- `video_no` (int): Video index (0-3)
- `callback` (string, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## Complete Example
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
$api = new VideoGenerationApi(null, $config);
try {
// Step 1: Generate video
$request = new VideoDiffusionRequest();
$request->setPrompt('a beautiful sunset over the ocean');
$request->setVideoType(1);
$response = $api->generateVideo($request);
$jobId = $response->getJobId();
echo "Video generation started: {$jobId}\n";
// Step 2: Wait for completion (see Task Management docs)
// ...
// Step 3: Extend the video
$extendRequest = new ExtendVideoRequest();
$extendRequest->setJobId($jobId);
$extendRequest->setVideoNo(0);
$extendRequest->setPrompt('continue with dramatic clouds');
$extendResponse = $api->extendVideo($extendRequest);
echo "Video extension started: " . $extendResponse->getJobId() . "\n";
// Step 4: Upscale the extended video
$upscaleRequest = new VideoUpscaleRequest();
$upscaleRequest->setJobId($extendResponse->getJobId());
$upscaleRequest->setVideoNo(0);
$upscaleResponse = $api->upscaleVideo($upscaleRequest);
echo "Video upscale started: " . $upscaleResponse->getJobId() . "\n";
} catch (\OpenAPI\Client\ApiException $e) {
echo "HTTP Status: " . $e->getCode() . "\n";
echo "Error Message: " . $e->getMessage() . "\n";
echo "Response Body: " . $e->getResponseBody() . "\n";
}
?>
```
---
## Error Handling
```php
generateVideo($request);
} catch (\OpenAPI\Client\ApiException $e) {
$statusCode = $e->getCode();
$errorBody = $e->getResponseBody();
switch ($statusCode) {
case 400:
echo "Validation error: Check request parameters\n";
break;
case 401:
echo "Authentication error: Invalid API key\n";
break;
case 404:
echo "Resource not found\n";
break;
case 429:
echo "Rate limit exceeded. Please retry later.\n";
break;
case 500:
case 502:
case 503:
echo "Server error. Please retry.\n";
break;
default:
echo "API error ({$statusCode}): {$errorBody}\n";
}
}
?>
```
---
## Retry Logic
```php
generateVideo($request);
} catch (\OpenAPI\Client\ApiException $e) {
if ($e->getCode() === 429) {
// Rate limited - wait and retry
$retries++;
sleep(5);
continue;
} elseif ($e->getCode() >= 500) {
// Server error - exponential backoff
$retries++;
$delay = pow(2, $retries);
sleep($delay);
if ($retries >= $maxRetries) {
throw $e;
}
continue;
} else {
// Other errors - don't retry
throw $e;
}
}
}
throw new Exception("Max retries exceeded");
}
// Usage
$request = new VideoDiffusionRequest();
$request->setPrompt('a flowing river');
$request->setVideoType(1);
try {
$response = generateVideoWithRetry($api, $request, 3);
echo "Job ID: " . $response->getJobId() . "\n";
} catch (Exception $e) {
echo "Failed after retries: " . $e->getMessage() . "\n";
}
?>
```
---
## Asynchronous Processing with Promises
For modern PHP with async support (using ReactPHP or Amp):
```php
generateVideo($request);
$resolve($response);
} catch (\OpenAPI\Client\ApiException $e) {
$reject($e);
}
});
}
// Usage
$promise = generateVideoAsync($api, $request);
$promise->then(
function ($response) {
echo "Job ID: " . $response->getJobId() . "\n";
},
function (\OpenAPI\Client\ApiException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
);
$loop->run();
?>
```
---
## Processing Multiple Videos
```php
setPrompt($prompt);
$request->setVideoType(1);
$response = $api->generateVideo($request);
$results[] = [
'prompt' => $prompt,
'job_id' => $response->getJobId(),
'status' => 'started'
];
} catch (\OpenAPI\Client\ApiException $e) {
$results[] = [
'prompt' => $prompt,
'error' => $e->getMessage(),
'status' => 'failed'
];
}
}
return $results;
}
// Usage
$prompts = ['sunset', 'mountains', 'ocean'];
$results = processMultipleVideos($api, $prompts);
foreach ($results as $result) {
if (isset($result['error'])) {
echo "Error for '{$result['prompt']}': {$result['error']}\n";
} else {
echo "Video '{$result['prompt']}': {$result['job_id']}\n";
}
}
?>
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/php/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/php/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/php/quickstart)
---
# Task Management
_Task status, polling, and error handling for PHP SDK_
## getTaskStatus()
Get current task status:
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
$taskApi = new TaskManagementApi(null, $config);
try {
$jobId = 'job-123';
$task = $taskApi->getTaskStatus($jobId);
echo "Status: " . $task->getStatus() . "\n";
echo "Progress: " . $task->getProgress() . "%\n";
if ($task->getStatus() === 'completed') {
echo "Result: " . print_r($task->getOutput(), true) . "\n";
}
} catch (\OpenAPI\Client\ApiException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>
```
---
## Polling for Completion
Wait for task completion with polling:
```php
getTaskStatus($jobId);
echo "Current status: " . $task->getStatus() . "\n";
if ($task->getStatus() === 'completed') {
echo "Task completed successfully!\n";
echo "Output: " . print_r($task->getOutput(), true) . "\n";
return $task;
} elseif ($task->getStatus() === 'failed') {
throw new Exception("Task failed: " . $task->getError());
}
// Check timeout
$elapsed = time() - $startTime;
if ($elapsed > $timeout) {
throw new Exception("Task timeout after {$timeoutSeconds} seconds");
}
// Wait before next poll
sleep($pollIntervalSeconds);
}
}
?>
```
**Usage:**
```php
getMessage() . "\n";
}
?>
```
---
## Complete Example with Error Handling
```php
setApiKey('x-api-key', getenv('LEGNEXT_API_KEY'));
$config->setHost('https://api.legnext.ai');
function waitForCompletion($taskApi, $jobId, $timeoutSeconds = 300, $pollIntervalSeconds = 3) {
$startTime = time();
while (true) {
$task = $taskApi->getTaskStatus($jobId);
if ($task->getStatus() === 'completed') {
return $task;
} elseif ($task->getStatus() === 'failed') {
throw new Exception("Task failed: " . $task->getError());
}
$elapsed = time() - $startTime;
if ($elapsed > $timeoutSeconds) {
throw new Exception("Task timeout after {$timeoutSeconds} seconds");
}
sleep($pollIntervalSeconds);
}
}
function handleApiError($e) {
$statusCode = $e->getCode();
$errorBody = $e->getResponseBody();
switch ($statusCode) {
case 400:
echo "Validation error: {$errorBody}\n";
break;
case 401:
echo "Authentication error: Invalid API key\n";
break;
case 404:
echo "Resource not found: {$errorBody}\n";
break;
case 429:
echo "Rate limit exceeded. Please retry later.\n";
break;
case 500:
case 502:
case 503:
echo "Server error: {$errorBody}\n";
break;
default:
echo "API error ({$statusCode}): {$errorBody}\n";
}
}
function generateImageWithPolling() {
global $config;
$imageApi = new ImageGenerationApi(null, $config);
$taskApi = new TaskManagementApi(null, $config);
try {
// Step 1: Start generation
$request = new DiffusionRequest();
$request->setText('a beautiful sunset over mountains');
$response = $imageApi->generateImage($request);
$jobId = $response->getJobId();
echo "Job started: {$jobId}\n";
// Step 2: Poll for completion
$result = waitForCompletion($taskApi, $jobId, 600, 3);
// Step 3: Get final result
$output = $result->getOutput();
if ($output !== null && $output->getImageUrls() !== null) {
echo "Image URLs: " . print_r($output->getImageUrls(), true) . "\n";
}
} catch (\OpenAPI\Client\ApiException $e) {
handleApiError($e);
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
}
generateImageWithPolling();
?>
```
---
## Error Handling
**HTTP Error Handling:**
```php
getTaskStatus($jobId);
} catch (\OpenAPI\Client\ApiException $e) {
$statusCode = $e->getCode();
$errorBody = $e->getResponseBody();
switch ($statusCode) {
case 400:
echo "Validation error: Check request parameters\n";
break;
case 401:
echo "Authentication error: Invalid API key\n";
break;
case 404:
echo "Resource not found: Check job ID exists\n";
break;
case 429:
echo "Rate limit exceeded. Please retry later.\n";
break;
case 500:
case 502:
case 503:
echo "Server error. Please retry with backoff.\n";
break;
default:
echo "API error ({$statusCode}): {$errorBody}\n";
}
}
?>
```
**Common HTTP Status Codes:**
| Status Code | Description | Action |
|-------------|-------------|--------|
| 400 | Invalid request parameters | Check request body format |
| 401 | Invalid API key | Verify API key is correct |
| 404 | Resource not found | Check job ID exists |
| 429 | Rate limit exceeded | Wait and retry with backoff |
| 500/502/503 | Server error | Retry with exponential backoff |
**Retry Logic with Exponential Backoff:**
```php
generateImage($request);
} catch (\OpenAPI\Client\ApiException $e) {
if ($e->getCode() === 429) {
// Rate limited - wait and retry
$retries++;
sleep(5);
continue;
} elseif ($e->getCode() >= 500) {
// Server error - exponential backoff
$retries++;
$delay = pow(2, $retries);
sleep($delay);
if ($retries >= $maxRetries) {
throw $e;
}
continue;
} else {
// Other errors - don't retry
throw $e;
}
}
}
throw new Exception("Max retries exceeded");
}
// Usage
$request = new DiffusionRequest();
$request->setText('a beautiful landscape');
try {
$response = callWithRetry($imageApi, $request, 3);
echo "Job ID: " . $response->getJobId() . "\n";
} catch (Exception $e) {
echo "Failed after retries: " . $e->getMessage() . "\n";
}
?>
```
---
## Processing Multiple Tasks
For processing multiple tasks sequentially:
```php
setText($prompt);
$response = $imageApi->generateImage($request);
$jobId = $response->getJobId();
echo "Started job for '{$prompt}': {$jobId}\n";
// Wait for completion
$result = waitForCompletion($taskApi, $jobId, 600, 3);
$output = $result->getOutput();
if ($output !== null && $output->getImageUrls() !== null && count($output->getImageUrls()) > 0) {
$results[] = [
'prompt' => $prompt,
'url' => $output->getImageUrls()[0]
];
}
} catch (Exception $e) {
$results[] = [
'prompt' => $prompt,
'error' => $e->getMessage()
];
}
}
return $results;
}
// Usage
$prompts = ['sunset', 'mountains', 'ocean'];
$results = generateMultipleImages($imageApi, $taskApi, $prompts);
foreach ($results as $result) {
if (isset($result['error'])) {
echo "Error for '{$result['prompt']}': {$result['error']}\n";
} else {
echo "Image '{$result['prompt']}': {$result['url']}\n";
}
}
?>
```
---
## Progress Callbacks
```php
getTaskStatus($jobId);
// Call progress callback
if ($onProgress !== null) {
$progress = $task->getProgress() ?? 0;
$status = $task->getStatus() ?? 'unknown';
call_user_func($onProgress, $progress, $status);
}
if ($task->getStatus() === 'completed') {
return $task;
} elseif ($task->getStatus() === 'failed') {
throw new Exception("Task failed: " . $task->getError());
}
$elapsed = time() - $startTime;
if ($elapsed > $timeoutSeconds) {
throw new Exception("Task timeout after {$timeoutSeconds} seconds");
}
sleep($pollIntervalSeconds);
}
}
// Usage
$result = waitForCompletionWithProgress(
$taskApi,
$jobId,
function($progress, $status) {
echo "Progress: {$progress}% - Status: {$status}\n";
},
600,
3
);
?>
```
---
## Laravel Integration
For Laravel applications, create a service class:
```php
setApiKey('x-api-key', config('legnext.api_key'));
$config->setHost(config('legnext.host'));
$this->imageApi = new ImageGenerationApi(null, $config);
$this->taskApi = new TaskManagementApi(null, $config);
}
public function generateImage($text, $callback = null)
{
$request = new DiffusionRequest();
$request->setText($text);
if ($callback !== null) {
$request->setCallback($callback);
}
return $this->imageApi->generateImage($request);
}
public function getTaskStatus($jobId)
{
return $this->taskApi->getTaskStatus($jobId);
}
public function waitForCompletion($jobId, $timeoutSeconds = 300, $pollIntervalSeconds = 3)
{
$startTime = time();
while (true) {
$task = $this->getTaskStatus($jobId);
if ($task->getStatus() === 'completed') {
return $task;
} elseif ($task->getStatus() === 'failed') {
throw new \Exception("Task failed: " . $task->getError());
}
$elapsed = time() - $startTime;
if ($elapsed > $timeoutSeconds) {
throw new \Exception("Task timeout after {$timeoutSeconds} seconds");
}
sleep($pollIntervalSeconds);
}
}
}
?>
```
**Usage in Controller:**
```php
legnext = $legnext;
}
public function generate(Request $request)
{
try {
$text = $request->input('text');
$response = $this->legnext->generateImage($text);
return response()->json([
'job_id' => $response->getJobId(),
'status' => $response->getStatus()
]);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function status($jobId)
{
try {
$task = $this->legnext->getTaskStatus($jobId);
return response()->json([
'status' => $task->getStatus(),
'progress' => $task->getProgress(),
'output' => $task->getOutput()
]);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
}
?>
```
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/php/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/php/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/php/quickstart)
---
# Installation
_Install the Legnext Ruby SDK_
## Requirements
- **Ruby**: Version 2.7 or higher
- **Bundler**: Latest version
## Install via RubyGems
```bash
gem install legnext-sdk
```
## Install via Bundler
Add this to your `Gemfile`:
```ruby
gem 'legnext-sdk', '~> 1.0.0'
```
Then run:
```bash
bundle install
```
## Verify Installation
```bash
gem list legnext-sdk
```
---
# Authentication
_Set up API authentication for Ruby SDK_
## Getting Your API Key
1. Visit [Legnext.ai Dashboard](https://legnext.ai/dashboard)
2. Navigate to API Keys section
3. Generate a new API key
4. Copy and store securely
## Authentication Methods
### Method 1: Environment Variables (Recommended)
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key-here"
```
Then use it in your Ruby code:
```ruby
require 'openapi_client'
# Configure API client
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = ''
end
# Create API instance
api = OpenapiClient::ImageApi.new
# Now you can use the API
# ...
```
### Method 2: Direct Initialization
Hardcode the API key directly (not recommended for production):
```ruby
require 'openapi_client'
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = 'your-api-key-here'
config.host = 'api.legnext.ai'
config.base_path = ''
end
api = OpenapiClient::ImageApi.new
```
### Method 3: Using dotenv Gem
Use the `dotenv` gem to load from `.env` files:
```bash
gem install dotenv
```
```ruby
require 'dotenv/load'
require 'openapi_client'
# .env file is automatically loaded
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = ''
end
api = OpenapiClient::ImageApi.new
```
**.env file:**
```
LEGNEXT_API_KEY=your-api-key-here
```
### Method 4: YAML Configuration File
Load API key from a YAML configuration file:
```ruby
require 'yaml'
require 'openapi_client'
# Load configuration
config_file = YAML.load_file('config.yml')
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = config_file['api_key']
config.host = 'api.legnext.ai'
config.base_path = ''
end
api = OpenapiClient::ImageApi.new
```
**config.yml:**
```yaml
api_key: your-api-key-here
environment: development
```
### Method 5: Rails Credentials (for Rails Applications)
For Rails 5.2+, use encrypted credentials:
```bash
rails credentials:edit
```
Add to credentials:
```yaml
legnext:
api_key: your-api-key-here
```
In your Rails app:
```ruby
require 'openapi_client'
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = Rails.application.credentials.legnext[:api_key]
config.host = 'api.legnext.ai'
config.base_path = ''
end
api = OpenapiClient::ImageApi.new
```
---
## Complete Configuration Example
```ruby
require 'openapi_client'
OpenapiClient.configure do |config|
# Required: API Key
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
# Required: API Host
config.host = 'api.legnext.ai'
config.base_path = ''
# Optional: Set debugging mode
config.debugging = ENV['LEGNEXT_DEBUG'] == 'true'
# Optional: Set timeout (in seconds)
config.timeout = 120
# Optional: Set custom user agent
config.user_agent = 'MyApp/1.0'
# Optional: SSL verification (recommended: true)
config.verify_ssl = true
config.verify_ssl_host = true
end
```
---
## Security Best Practices
1. **Never commit API keys to version control**
```ruby
# .gitignore
.env
config.yml
config/credentials/*.yml.enc
```
2. **Use environment variables in production**
```bash
# Set in your deployment environment
export LEGNEXT_API_KEY="your-production-key"
```
3. **Rotate keys regularly**
- Generate new keys periodically
- Revoke old keys after rotation
4. **Use different keys for development and production**
```ruby
OpenapiClient.configure do |config|
api_key = if ENV['RAILS_ENV'] == 'production'
ENV['LEGNEXT_PROD_API_KEY']
else
ENV['LEGNEXT_DEV_API_KEY']
end
config.api_key['x-api-key'] = api_key
config.host = 'api.legnext.ai'
config.base_path = ''
end
```
5. **Restrict API key permissions**
- Use the minimum required permissions
- Monitor usage through the dashboard
6. **Enable SSL verification**
```ruby
OpenapiClient.configure do |config|
config.verify_ssl = true
config.verify_ssl_host = true
end
```
---
## Testing Authentication
Verify your API key is working:
```ruby
require 'openapi_client'
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = ''
end
api_key = ENV['LEGNEXT_API_KEY']
account_api = OpenapiClient::AccountManagementApi.new
begin
# Test with account balance endpoint
response = account_api.api_account_balance_get({x_api_key: api_key})
puts "✅ Authentication successful!"
if response.data
puts "Balance: $#{response.data.balance_usd}"
end
rescue OpenapiClient::ApiError => e
if e.code == 401
puts "❌ Authentication failed: Invalid API key"
else
puts "❌ Error: #{e.message}"
end
end
```
---
## Debugging
Enable debugging to see HTTP requests and responses:
```ruby
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = ''
config.debugging = true # Enable debug output
config.logger = Logger.new(STDOUT) # Custom logger
config.logger.level = Logger::DEBUG
end
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/ruby/image-generation)
- [Video Generation](https://docs.legnext.ai/sdk/ruby/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/ruby/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/ruby/quickstart)
---
# Quick Start
_Get started with the Legnext Ruby SDK_
## 1. Install
```bash
gem install legnext-ruby-sdk
```
## 2. Set API Key
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
```ruby
require 'openapi_client'
# Configure API client
OpenapiClient.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = ''
end
# Create API instance
api = OpenapiClient::ImageApi.new
begin
# Generate image
request = {
text: 'a beautiful sunset over mountains'
}
response = api.api_v1_diffusion_post(request)
puts "Response: #{response}"
rescue OpenapiClient::ApiError => e
puts "Error: #{e.message}"
end
```
## 4. Check Task Status
```ruby
video_api = OpenapiClient::VideoApi.new
begin
task_response = video_api.api_v1_job_job_id_get(job_id)
puts "Status: #{task_response.status}"
if task_response.output
puts "Images: #{task_response.output.image_urls}"
end
rescue OpenapiClient::ApiError => e
puts "Error: #{e.message}"
end
```
## Error Handling
```ruby
begin
response = api.api_v1_diffusion_post(request)
rescue OpenapiClient::ApiError => e
puts "HTTP Status: #{e.code}"
puts "Error Message: #{e.message}"
puts "Response Body: #{e.response_body}"
puts "Response Headers: #{e.response_headers}"
end
```
## Available APIs
- `ImageApi` - Text to image, variations, upscaling, editing
- `VideoApi` - Video generation, upscaling, and task status
- `AccountManagementApi` - Account balance and information
---
# Image Generation
_Image generation API reference for Ruby SDK_
## generate_image()
Create a new text-to-image generation task.
```ruby
require 'legnext_sdk'
# Configure API client
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
api = Legnext::ImageGenerationApi.new
begin
request = Legnext::DiffusionRequest.new(
text: 'a serene mountain landscape at sunset',
callback: 'https://your-domain.com/webhook'
)
response = api.generate_image(request)
puts "Job ID: #{response.job_id}"
puts "Status: #{response.status}"
rescue Legnext::ApiError => e
puts "Error: #{e.message}"
end
```
**Parameters:**
- `text` (String): Text prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL for completion notification
**Returns:** Response with `job_id` and `status`
---
## vary_image()
Create variations of a generated image.
```ruby
request = Legnext::VaryRequest.new(
job_id: 'original-job-id',
image_no: 0,
type: 1, # 0=Subtle, 1=Strong
remix_prompt: 'add more clouds'
)
response = api.vary_image(request)
puts "Variation Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `type` (Integer): Variation type (0=Subtle, 1=Strong)
- `remix_prompt` (String, optional): Additional prompt for variation
---
## upscale_image()
Upscale a generated image to higher resolution.
```ruby
request = Legnext::UpscaleRequest.new(
job_id: 'original-job-id',
image_no: 0,
type: 1 # 0=Subtle, 1=Creative
)
response = api.upscale_image(request)
puts "Upscale Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `type` (Integer): Upscale type (0=Subtle, 1=Creative)
---
## reroll_image()
Regenerate with the same prompt.
```ruby
request = Legnext::RerollRequest.new(
job_id: 'original-job-id'
)
response = api.reroll_image(request)
puts "Reroll Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
---
## blend_images()
Blend 2-5 images together.
```ruby
request = Legnext::BlendRequest.new(
img_urls: [
'https://example.com/image1.png',
'https://example.com/image2.png'
],
aspect_ratio: '1:1' # Options: 1:1, 16:9, 9:16, 3:2, 2:3
)
response = api.blend_images(request)
puts "Blend Job ID: #{response.job_id}"
```
**Parameters:**
- `img_urls` (Array): Array of 2-5 image URLs
- `aspect_ratio` (String, optional): Output aspect ratio (1:1, 16:9, 9:16, 3:2, 2:3)
---
## describe_image()
Generate text descriptions from an image.
```ruby
request = Legnext::DescribeRequest.new(
img_url: 'https://example.com/image.png'
)
response = api.describe_image(request)
puts "Describe Job ID: #{response.job_id}"
```
**Parameters:**
- `img_url` (String): URL of the image to describe
---
## edit_image()
Edit an image with text description.
```ruby
request = Legnext::EditRequest.new(
job_id: 'original-job-id',
image_no: 0,
canvas: 'original', # Canvas to edit
img_pos: 0, # Image position
remix_prompt: 'change the sky to sunset colors',
callback: 'https://your-domain.com/webhook'
)
response = api.edit_image(request)
puts "Edit Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `canvas` (String): Canvas to edit
- `img_pos` (Integer): Image position
- `remix_prompt` (String): Edit instructions
- `callback` (String, optional): Webhook URL
---
## inpaint_image()
Fill masked regions in an image.
```ruby
request = Legnext::InpaintRequest.new(
job_id: 'original-job-id',
image_no: 0,
remix_prompt: 'fill with forest landscape',
mask: {
type: 'url',
value: 'https://example.com/mask.png'
},
callback: 'https://your-domain.com/webhook'
)
response = api.inpaint_image(request)
puts "Inpaint Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `remix_prompt` (String): Inpainting prompt
- `mask` (Hash): Mask structure with `type` and `value`
- `callback` (String, optional): Webhook URL
---
## outpaint_image()
Extend image boundaries.
```ruby
request = Legnext::OutpaintRequest.new(
job_id: 'original-job-id',
image_no: 0,
scale: 1.5, # Scale factor (1.1-3.0)
remix_prompt: 'extend with matching scenery',
callback: 'https://your-domain.com/webhook'
)
response = api.outpaint_image(request)
puts "Outpaint Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `scale` (Float): Scale factor for extension (1.1-3.0)
- `remix_prompt` (String, optional): Additional prompt for outpainting
- `callback` (String, optional): Webhook URL
---
## pan_image()
Create panoramic or panned views.
```ruby
request = Legnext::PanRequest.new(
job_id: 'original-job-id',
image_no: 0,
direction: 3, # Direction (0=Down, 1=Right, 2=Up, 3=Left)
scale: 1.5, # Scale factor (1.1-3.0)
remix_prompt: 'continue the landscape naturally',
callback: 'https://your-domain.com/webhook'
)
response = api.pan_image(request)
puts "Pan Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `direction` (Integer): Pan direction (0=Down, 1=Right, 2=Up, 3=Left)
- `scale` (Float): Scale factor (1.1-3.0)
- `remix_prompt` (String, optional): Additional prompt for panning
- `callback` (String, optional): Webhook URL
---
## remix_image()
Apply a remix effect to an image with different intensity.
```ruby
request = Legnext::RemixRequest.new(
job_id: 'original-job-id',
image_no: 0,
mode: 0, # Mode (0=Strong, 1=Subtle)
remix_prompt: 'adjust colors and lighting',
callback: 'https://your-domain.com/webhook'
)
response = api.remix_image(request)
puts "Remix Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original image job ID
- `image_no` (Integer): Image index (0-3)
- `mode` (Integer): Remix mode (0=Strong, 1=Subtle)
- `remix_prompt` (String, optional): Additional prompt for remix
- `callback` (String, optional): Webhook URL
---
## shorten_prompt()
Optimize and simplify prompts.
```ruby
request = Legnext::ShortenRequest.new(
prompt: 'your very long and detailed prompt here with lots of unnecessary words and descriptions that could be made more concise...'
)
response = api.shorten_prompt(request)
puts "Shortened prompt: #{response.shortened_prompt}"
```
**Parameters:**
- `prompt` (String): Long prompt to optimize
**Returns:** Response with `shortened_prompt`
---
## Complete Example
```ruby
require 'legnext_sdk'
# Configure API client
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
api = Legnext::ImageGenerationApi.new
begin
# Step 1: Generate image
request = Legnext::DiffusionRequest.new(
text: 'a beautiful sunset over mountains',
callback: 'https://your-domain.com/webhook'
)
response = api.generate_image(request)
job_id = response.job_id
puts "Image generation started: #{job_id}"
# Step 2: Wait for completion (see Task Management docs)
# ...
# Step 3: Upscale the first image
upscale_request = Legnext::UpscaleRequest.new(
job_id: job_id,
image_no: 0,
type: 1,
callback: 'https://your-domain.com/webhook'
)
upscale_response = api.upscale_image(upscale_request)
puts "Upscale started: #{upscale_response.job_id}"
rescue Legnext::ApiError => e
puts "HTTP Status: #{e.code}"
puts "Error Message: #{e.message}"
puts "Response Body: #{e.response_body}"
end
```
---
## Error Handling
```ruby
begin
response = api.generate_image(request)
rescue Legnext::ApiError => e
case e.code
when 400
puts "Validation error: Check request parameters"
when 401
puts "Authentication error: Invalid API key"
when 404
puts "Resource not found"
when 429
puts "Rate limit exceeded. Please retry later."
when 500, 502, 503
puts "Server error. Please retry."
else
puts "API error (#{e.code}): #{e.message}"
end
puts "Response body: #{e.response_body}"
end
```
---
## Using Blocks
Ruby idiomatic way with blocks:
```ruby
require 'legnext_sdk'
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
def generate_with_retry(api, request, max_retries = 3)
retries = 0
begin
api.generate_image(request)
rescue Legnext::ApiError => e
if e.code == 429 && retries < max_retries
retries += 1
sleep 5
retry
elsif e.code >= 500 && retries < max_retries
retries += 1
sleep(2**retries)
retry
else
raise
end
end
end
api = Legnext::ImageGenerationApi.new
request = Legnext::DiffusionRequest.new(
text: 'a beautiful landscape',
callback: 'https://your-domain.com/webhook'
)
response = generate_with_retry(api, request)
puts "Job ID: #{response.job_id}"
```
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/ruby/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/ruby/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/ruby/quickstart)
---
# Video Generation
_Video generation API reference for Ruby SDK_
## generate_video()
Generate a video from text prompt with optional image URL.
```ruby
require 'legnext_sdk'
# Configure API client
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
api = Legnext::VideoGenerationApi.new
begin
# Mode 1: Generate from text only
request = Legnext::VideoDiffusionRequest.new(
prompt: 'a flowing river through mountains',
video_type: 1, # 0=480p, 1=720p
callback: 'https://your-domain.com/webhook'
)
response = api.generate_video(request)
puts "Job ID: #{response.job_id}"
puts "Status: #{response.status}"
rescue Legnext::ApiError => e
puts "Error: #{e.message}"
end
```
**Mode 2: Generate from image URL in prompt:**
```ruby
# Generate video from image included in prompt
request = Legnext::VideoDiffusionRequest.new(
prompt: 'https://example.com/image.png a flowing river through mountains',
video_type: 1,
callback: 'https://your-domain.com/webhook'
)
response = api.generate_video(request)
puts "Job ID: #{response.job_id}"
```
**Mode 3: Animate existing image:**
```ruby
# Animate an image from a previous generation job
request = Legnext::VideoDiffusionRequest.new(
job_id: 'previous-image-job-id',
image_no: 0,
prompt: 'flowing movement through the landscape',
video_type: 1,
callback: 'https://your-domain.com/webhook'
)
response = api.generate_video(request)
puts "Job ID: #{response.job_id}"
```
**Parameters:**
- `prompt` (String): Video prompt or "[image_url] prompt text" (1-8192 characters)
- `job_id` (String, optional): Original image job ID (for image animation mode)
- `image_no` (Integer, optional): Image index (0-3) (for image animation mode)
- `video_type` (Integer, optional): Quality (0=480p, 1=720p)
- `callback` (String, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## extend_video()
Extend an existing video.
```ruby
request = Legnext::ExtendVideoRequest.new(
job_id: 'original-video-job-id',
video_no: 0,
prompt: 'continue with dramatic lighting',
callback: 'https://your-domain.com/webhook'
)
response = api.extend_video(request)
puts "Extension Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original video task ID
- `video_no` (Integer): Video index (0-3)
- `prompt` (String, optional): Extension prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## upscale_video()
Upscale video to higher resolution.
```ruby
request = Legnext::VideoUpscaleRequest.new(
job_id: 'original-video-job-id',
video_no: 0,
callback: 'https://your-domain.com/webhook'
)
response = api.upscale_video(request)
puts "Upscale Job ID: #{response.job_id}"
```
**Parameters:**
- `job_id` (String): Original video task ID
- `video_no` (Integer): Video index (0-3)
- `callback` (String, optional): Webhook URL
**Returns:** Response with `job_id` and `status`
---
## Complete Example
```ruby
require 'legnext_sdk'
# Configure API client
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
api = Legnext::VideoGenerationApi.new
begin
# Step 1: Generate video
request = Legnext::VideoDiffusionRequest.new(
prompt: 'a beautiful sunset over the ocean',
video_type: 1,
callback: 'https://your-domain.com/webhook'
)
response = api.generate_video(request)
job_id = response.job_id
puts "Video generation started: #{job_id}"
# Step 2: Wait for completion (see Task Management docs)
# ...
# Step 3: Extend the video
extend_request = Legnext::ExtendVideoRequest.new(
job_id: job_id,
video_no: 0,
prompt: 'continue with dramatic clouds',
callback: 'https://your-domain.com/webhook'
)
extend_response = api.extend_video(extend_request)
puts "Video extension started: #{extend_response.job_id}"
# Step 4: Upscale the extended video
upscale_request = Legnext::VideoUpscaleRequest.new(
job_id: extend_response.job_id,
video_no: 0,
callback: 'https://your-domain.com/webhook'
)
upscale_response = api.upscale_video(upscale_request)
puts "Video upscale started: #{upscale_response.job_id}"
rescue Legnext::ApiError => e
puts "HTTP Status: #{e.code}"
puts "Error Message: #{e.message}"
puts "Response Body: #{e.response_body}"
end
```
---
## Error Handling
```ruby
begin
response = api.generate_video(request)
rescue Legnext::ApiError => e
case e.code
when 400
puts "Validation error: Check request parameters"
when 401
puts "Authentication error: Invalid API key"
when 404
puts "Resource not found"
when 429
puts "Rate limit exceeded. Please retry later."
when 500, 502, 503
puts "Server error. Please retry."
else
puts "API error (#{e.code}): #{e.message}"
end
puts "Response body: #{e.response_body}"
end
```
---
## Retry Logic
```ruby
def generate_video_with_retry(api, request, max_retries = 3)
retries = 0
begin
api.generate_video(request)
rescue Legnext::ApiError => e
if e.code == 429 && retries < max_retries
# Rate limited - wait and retry
retries += 1
sleep 5
retry
elsif e.code >= 500 && retries < max_retries
# Server error - exponential backoff
retries += 1
sleep(2**retries)
retry
else
# Other errors - don't retry
raise
end
end
end
# Usage
api = Legnext::VideoGenerationApi.new
request = Legnext::VideoDiffusionRequest.new(
prompt: 'a flowing river',
video_type: 1,
callback: 'https://your-domain.com/webhook'
)
response = generate_video_with_retry(api, request)
puts "Job ID: #{response.job_id}"
```
---
## Asynchronous Processing with Threads
```ruby
require 'thread'
def process_multiple_videos(api, prompts)
threads = []
results = Queue.new
prompts.each do |prompt|
threads << Thread.new do
begin
request = Legnext::VideoDiffusionRequest.new(
prompt: prompt,
video_type: 1,
callback: 'https://your-domain.com/webhook'
)
response = api.generate_video(request)
results << { prompt: prompt, job_id: response.job_id }
rescue Legnext::ApiError => e
results << { prompt: prompt, error: e.message }
end
end
end
# Wait for all threads
threads.each(&:join)
# Collect results
all_results = []
all_results << results.pop until results.empty?
all_results
end
# Usage
api = Legnext::VideoGenerationApi.new
prompts = ['sunset', 'mountains', 'ocean']
results = process_multiple_videos(api, prompts)
results.each do |result|
if result[:error]
puts "Error for '#{result[:prompt]}': #{result[:error]}"
else
puts "Video '#{result[:prompt]}': #{result[:job_id]}"
end
end
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/ruby/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/ruby/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/ruby/quickstart)
---
# Task Management
_Task status, polling, and error handling for Ruby SDK_
## get_task_status()
Get current task status:
```ruby
require 'legnext_sdk'
# Configure API client
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
task_api = Legnext::TaskManagementApi.new
begin
job_id = 'job-123'
task = task_api.get_task_status(job_id)
puts "Status: #{task.status}"
puts "Progress: #{task.progress}%"
if task.status == 'completed'
puts "Result: #{task.output}"
end
rescue Legnext::ApiError => e
puts "Error: #{e.message}"
end
```
---
## Polling for Completion
Wait for task completion with polling:
```ruby
def wait_for_completion(task_api, job_id, timeout_seconds = 300, poll_interval_seconds = 3)
start_time = Time.now
timeout = timeout_seconds
loop do
task = task_api.get_task_status(job_id)
puts "Current status: #{task.status}"
if task.status == 'completed'
puts "Task completed successfully!"
puts "Output: #{task.output}"
return task
elsif task.status == 'failed'
raise "Task failed: #{task.error}"
end
# Check timeout
elapsed = Time.now - start_time
if elapsed > timeout
raise "Task timeout after #{timeout_seconds} seconds"
end
# Wait before next poll
sleep poll_interval_seconds
end
end
```
**Usage:**
```ruby
task_api = Legnext::TaskManagementApi.new
job_id = 'job-123'
begin
result = wait_for_completion(task_api, job_id, 300, 3)
puts "Final result: #{result}"
rescue StandardError => e
puts "Error: #{e.message}"
end
```
---
## Complete Example with Error Handling
```ruby
require 'legnext_sdk'
# Configure API client
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
def wait_for_completion(task_api, job_id, timeout_seconds = 300, poll_interval_seconds = 3)
start_time = Time.now
timeout = timeout_seconds
loop do
task = task_api.get_task_status(job_id)
if task.status == 'completed'
return task
elsif task.status == 'failed'
raise "Task failed: #{task.error}"
end
elapsed = Time.now - start_time
if elapsed > timeout
raise "Task timeout after #{timeout_seconds} seconds"
end
sleep poll_interval_seconds
end
end
def generate_image_with_polling
image_api = Legnext::ImageGenerationApi.new
task_api = Legnext::TaskManagementApi.new
# Step 1: Start generation
request = Legnext::DiffusionRequest.new(
text: 'a beautiful sunset over mountains'
)
response = image_api.generate_image(request)
job_id = response.job_id
puts "Job started: #{job_id}"
# Step 2: Poll for completion
result = wait_for_completion(task_api, job_id, 600, 3)
# Step 3: Get final result
if result.output && result.output.image_urls
puts "Image URLs: #{result.output.image_urls}"
end
rescue Legnext::ApiError => e
handle_api_error(e)
rescue StandardError => e
puts "Error: #{e.message}"
end
def handle_api_error(error)
case error.code
when 400
puts "Validation error: #{error.response_body}"
when 401
puts "Authentication error: Invalid API key"
when 404
puts "Resource not found: #{error.response_body}"
when 429
puts "Rate limit exceeded. Please retry later."
when 500, 502, 503
puts "Server error: #{error.response_body}"
else
puts "API error (#{error.code}): #{error.response_body}"
end
end
generate_image_with_polling
```
---
## Error Handling
**HTTP Error Handling:**
```ruby
begin
task = task_api.get_task_status(job_id)
rescue Legnext::ApiError => e
case e.code
when 400
puts "Validation error: Check request parameters"
when 401
puts "Authentication error: Invalid API key"
when 404
puts "Resource not found: Check job ID exists"
when 429
puts "Rate limit exceeded. Please retry later."
when 500, 502, 503
puts "Server error. Please retry with backoff."
else
puts "API error (#{e.code}): #{e.message}"
end
puts "Response body: #{e.response_body}"
end
```
**Common HTTP Status Codes:**
| Status Code | Description | Action |
|-------------|-------------|--------|
| 400 | Invalid request parameters | Check request body format |
| 401 | Invalid API key | Verify API key is correct |
| 404 | Resource not found | Check job ID exists |
| 429 | Rate limit exceeded | Wait and retry with backoff |
| 500/502/503 | Server error | Retry with exponential backoff |
**Retry Logic with Exponential Backoff:**
```ruby
def call_with_retry(image_api, request, max_retries = 3)
retries = 0
begin
image_api.generate_image(request)
rescue Legnext::ApiError => e
if e.code == 429 && retries < max_retries
# Rate limited - wait and retry
retries += 1
sleep 5
retry
elsif e.code >= 500 && retries < max_retries
# Server error - exponential backoff
retries += 1
delay = 2**retries
sleep delay
retry if retries < max_retries
raise
else
# Other errors - don't retry
raise
end
end
end
# Usage
image_api = Legnext::ImageGenerationApi.new
request = Legnext::DiffusionRequest.new(text: 'a beautiful landscape')
begin
response = call_with_retry(image_api, request, 3)
puts "Job ID: #{response.job_id}"
rescue Legnext::ApiError => e
puts "Failed after retries: #{e.message}"
end
```
---
## Concurrent Operations with Threads
For processing multiple tasks concurrently:
```ruby
require 'thread'
def generate_multiple_images
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
image_api = Legnext::ImageGenerationApi.new
task_api = Legnext::TaskManagementApi.new
prompts = ['sunset', 'mountains', 'ocean']
threads = []
results = Queue.new
prompts.each do |prompt|
threads << Thread.new do
begin
# Start generation
request = Legnext::DiffusionRequest.new(text: prompt)
response = image_api.generate_image(request)
job_id = response.job_id
# Wait for completion
result = wait_for_completion(task_api, job_id, 600, 3)
if result.output && result.output.image_urls && !result.output.image_urls.empty?
results << { prompt: prompt, url: result.output.image_urls[0] }
end
rescue StandardError => e
results << { prompt: prompt, error: e.message }
end
end
end
# Wait for all threads
threads.each(&:join)
# Collect results
all_results = []
all_results << results.pop until results.empty?
all_results.each do |result|
if result[:error]
puts "Error for '#{result[:prompt]}': #{result[:error]}"
else
puts "Image '#{result[:prompt]}': #{result[:url]}"
end
end
end
generate_multiple_images
```
---
## Progress Callbacks
```ruby
def wait_for_completion_with_progress(task_api, job_id, timeout_seconds = 300, poll_interval_seconds = 3, &block)
start_time = Time.now
timeout = timeout_seconds
loop do
task = task_api.get_task_status(job_id)
# Call progress callback
if block_given?
progress = task.progress || 0
status = task.status || 'unknown'
yield(progress, status)
end
if task.status == 'completed'
return task
elsif task.status == 'failed'
raise "Task failed: #{task.error}"
end
elapsed = Time.now - start_time
if elapsed > timeout
raise "Task timeout after #{timeout_seconds} seconds"
end
sleep poll_interval_seconds
end
end
# Usage
task_api = Legnext::TaskManagementApi.new
job_id = 'job-123'
result = wait_for_completion_with_progress(task_api, job_id, 600, 3) do |progress, status|
puts "Progress: #{progress}% - Status: #{status}"
end
```
---
## Using Fibers for Cooperative Multitasking
```ruby
require 'fiber'
def create_image_fiber(image_api, task_api, prompt)
Fiber.new do
# Start generation
request = Legnext::DiffusionRequest.new(text: prompt)
response = image_api.generate_image(request)
job_id = response.job_id
Fiber.yield job_id
# Poll for completion
loop do
task = task_api.get_task_status(job_id)
if task.status == 'completed'
Fiber.yield task.output
break
elsif task.status == 'failed'
raise "Task failed: #{task.error}"
end
Fiber.yield :pending
sleep 3
end
end
end
# Usage
Legnext.configure do |config|
config.api_key['x-api-key'] = ENV['LEGNEXT_API_KEY']
config.host = 'api.legnext.ai'
config.base_path = '/api'
end
image_api = Legnext::ImageGenerationApi.new
task_api = Legnext::TaskManagementApi.new
fiber = create_image_fiber(image_api, task_api, 'a beautiful landscape')
job_id = fiber.resume
puts "Job started: #{job_id}"
loop do
result = fiber.resume
break unless fiber.alive?
if result == :pending
puts "Still processing..."
elsif result
puts "Result: #{result}"
end
end
```
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/ruby/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/ruby/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/ruby/quickstart)
---
# Installation
_Install the Legnext C#/.NET SDK_
## Requirements
- **.NET**: Version 6.0 or higher (or .NET Framework 4.6.2+)
- **NuGet**: Package manager
## Install via NuGet
### Using Package Manager Console
```powershell
Install-Package Legnext.SDK
```
### Using .NET CLI
```bash
dotnet add package Legnext.SDK
```
### Using Package Reference
Add to your `.csproj` file:
```xml
```
## Verify Installation
```bash
dotnet list package | grep Legnext
```
---
# Authentication
_Set up API authentication for C#/.NET SDK_
## Getting Your API Key
1. Visit [Legnext.ai Dashboard](https://legnext.ai/dashboard)
2. Navigate to API Keys section
3. Generate a new API key
4. Copy and store securely
## Authentication Methods
### Method 1: Environment Variables (Recommended)
Set your API key as an environment variable:
```bash
export LEGNEXT_API_KEY="your-api-key-here"
```
Then use it in your C# code:
```csharp
using System;
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 imageApi = provider.GetRequiredService();
// Use imageApi with apiKey in method calls
var response = await imageApi.ApiV1DiffusionPostAsync(
new Option(apiKey),
request
);
```
### Method 2: appsettings.json Configuration
For ASP.NET Core applications:
**appsettings.json:**
```json
{
"Legnext": {
"ApiKey": "your-api-key-here",
"BaseUrl": "https://api.legnext.ai"
}
}
```
**Usage:**
```csharp
string apiKey = Configuration["Legnext:ApiKey"];
string baseUrl = Configuration["Legnext:BaseUrl"];
```
### Method 3: User Secrets (Development)
For development environments:
```bash
dotnet user-secrets init
dotnet user-secrets set "Legnext:ApiKey" "your-api-key-here"
```
Then access in code:
```csharp
string apiKey = Configuration["Legnext:ApiKey"];
```
---
## Complete Setup Example
```csharp
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Legnext.SDK.Api;
using Legnext.SDK.Client;
using Legnext.SDK.Extensions;
public class LegnextService
{
private readonly IServiceProvider _serviceProvider;
private readonly string _apiKey;
public LegnextService(string apiKey)
{
_apiKey = apiKey;
var services = new ServiceCollection();
services.AddApi(config =>
{
config.AddApiHttpClients(client =>
{
client.BaseAddress = new Uri("https://api.legnext.ai");
client.Timeout = TimeSpan.FromMinutes(5);
});
});
_serviceProvider = services.BuildServiceProvider();
}
public async Task GenerateImageAsync(string prompt)
{
var imageApi = _serviceProvider.GetRequiredService();
var request = new Dictionary
{
{ "text", prompt }
};
var response = await imageApi.ApiV1DiffusionPostAsync(
new Option(_apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
return jobId.GetString();
}
}
throw new Exception("Failed to generate image");
}
}
```
---
## Security Best Practices
1. **Never hardcode API keys**
2. **Use different keys for different environments**
3. **Never commit secrets to version control**
4. **Rotate keys regularly**
5. **Use secure storage in production** (Azure Key Vault, AWS Secrets Manager)
6. **Enable HTTPS only**
---
## Testing Authentication
```csharp
using System;
using System.Text.Json;
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 accountApi = provider.GetRequiredService();
try
{
var response = await accountApi.ApiAccountBalanceGetAsync(
new Option(apiKey)
);
if (response.IsOk)
{
Console.WriteLine("✅ Authentication successful!");
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("data", out var data))
{
if (data.TryGetProperty("balance_usd", out var balance))
{
Console.WriteLine($"Balance: ${balance.GetDecimal()} USD");
}
}
}
}
catch (Exception e)
{
Console.WriteLine("❌ Authentication failed");
Console.WriteLine($"Error: {e.Message}");
}
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/csharp/image-generation)
- [Video Generation](https://docs.legnext.ai/sdk/csharp/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/csharp/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/csharp/quickstart)
---
# Quick Start
_Get started with the Legnext C#/.NET SDK_
## 1. Install
```bash
dotnet add package Legnext.SDK
```
## 2. Set API Key
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
```csharp
using System;
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");
// Set up dependency injection
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();
try
{
// Generate image
var request = new Dictionary
{
{ "text", "a beautiful sunset over mountains" }
};
var response = await imageApi.ApiV1DiffusionPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Job ID: {jobId.GetString()}");
}
if (jsonDoc.RootElement.TryGetProperty("status", out var status))
{
Console.WriteLine($"Status: {status.GetString()}");
}
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
```
## 4. Check Task Status
```csharp
using System.Text.Json;
using Legnext.SDK.Api;
var videoApi = provider.GetRequiredService();
try
{
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option(apiKey)
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
var root = jsonDoc.RootElement;
if (root.TryGetProperty("status", out var status))
{
Console.WriteLine($"Status: {status.GetString()}");
}
if (root.TryGetProperty("task_type", out var taskType))
{
Console.WriteLine($"Task Type: {taskType.GetString()}");
}
if (root.TryGetProperty("output", out var output) &&
output.TryGetProperty("image_urls", out var imageUrls))
{
Console.WriteLine("Images:");
foreach (var url in imageUrls.EnumerateArray())
{
Console.WriteLine($" - {url.GetString()}");
}
}
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
```
## Error Handling
```csharp
try
{
var response = await imageApi.ApiV1DiffusionPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
// Parse and handle successful response
var jsonDoc = JsonDocument.Parse(response.RawContent);
// Process result...
}
else
{
Console.WriteLine($"Request failed with status: {response.StatusCode}");
Console.WriteLine($"Response: {response.RawContent}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
```
## Available APIs
- `IImageApi` - Text to image, variations, upscaling, editing
- `IVideoApi` - Video generation, upscaling, and task status
- `IAccountManagementApi` - Account balance and information
## Important Notes
- The SDK uses dependency injection with `Microsoft.Extensions.DependencyInjection`
- Namespace is `Legnext.SDK.*`
- API methods use `Option` types for optional parameters
- Responses provide `IsOk` property and `RawContent` for result data
- Base URL is `https://api.legnext.ai` (no `/api` suffix)
---
# Image Generation
_Generate and manipulate images using C#/.NET SDK_
## Setup
```csharp
using System;
using System.Text.Json;
using System.Collections.Generic;
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 imageApi = provider.GetRequiredService();
```
## Text-to-Image (Diffusion)
Generate images from text descriptions:
```csharp
var request = new Dictionary
{
{ "text", "a beautiful sunset over mountains" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1DiffusionPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Job ID: {jobId.GetString()}");
}
}
```
**With Additional Parameters:**
```csharp
var request = new Dictionary
{
{ "text", "a futuristic city at night" },
{ "aspect_ratio", "16:9" },
{ "version", "6.1" },
{ "quality", "high" },
{ "callback", "https://example.com/callback" }
};
```
## Image Upscaling
Enhance image resolution:
```csharp
var request = new Dictionary
{
{ "job_id", "original-job-id" },
{ "imageNo", 0 }, // Index of image to upscale (0-3)
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1UpscalePostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Upscale Job ID: {jobId.GetString()}");
}
}
```
## Image Variation
Create variations of existing images:
```csharp
var request = new Dictionary
{
{ "job_id", "original-job-id" },
{ "imageNo", 2 }, // Which image to vary (0-3)
{ "remixPrompt", "same image but with different colors" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1VariationPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Variation Job ID: {jobId.GetString()}");
}
}
```
## Image Blending
Combine multiple images:
```csharp
var request = new Dictionary
{
{ "imgUrls", new List
{
"https://example.com/image1.jpg",
"https://example.com/image2.jpg"
}
},
{ "aspect_ratio", "1:1" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1BlendPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
// Process response...
}
```
## Image Editing
Edit specific parts of an image:
```csharp
var request = new Dictionary
{
{ "canvas", new Dictionary
{
{ "width", 512 },
{ "height", 512 }
}
},
{ "imgPos", new Dictionary
{
{ "x", 0 },
{ "y", 0 }
}
},
{ "remixPrompt", "add a rainbow in the sky" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1EditPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
// Process response...
}
```
## Image Inpainting
Inpaint specific regions of an image:
```csharp
var request = new Dictionary
{
{ "mask", new Dictionary
{
{ "x", 0 },
{ "y", 0 },
{ "width", 256 },
{ "height", 256 }
}
},
{ "remixPrompt", "a detailed painting" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1InpaintPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Inpaint Job ID: {jobId.GetString()}");
}
}
```
## Image Outpainting
Extend image boundaries:
```csharp
var request = new Dictionary
{
{ "scale", 1.5 }, // Scaling factor (1.1-3.0)
{ "remixPrompt", "extend the scene naturally" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1OutpaintPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Outpaint Job ID: {jobId.GetString()}");
}
}
```
## Image Panning
Pan across an image:
```csharp
var request = new Dictionary
{
{ "direction", 0 }, // 0=Down, 1=Right, 2=Up, 3=Left
{ "scale", 1.5 }, // Scaling factor (1.1-3.0)
{ "remixPrompt", "continue the scene" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1PanPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Pan Job ID: {jobId.GetString()}");
}
}
```
## Image Remixing
Remix an image with a different style or concept:
```csharp
var request = new Dictionary
{
{ "job_id", "original-job-id" },
{ "imageNo", 1 }, // Which image to remix (0-3)
{ "mode", 0 }, // 0=Strong, 1=Subtle
{ "remixPrompt", "same scene but in oil painting style" },
{ "callback", "https://example.com/callback" }
};
var response = await imageApi.ApiV1RemixPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Remix Job ID: {jobId.GetString()}");
}
}
```
## Response Handling
All responses follow this pattern:
```csharp
var response = await imageApi.SomeMethodAsync(...);
if (response.IsOk)
{
// Parse the JSON response
var jsonDoc = JsonDocument.Parse(response.RawContent);
var root = jsonDoc.RootElement;
// Access properties
if (root.TryGetProperty("job_id", out var jobId))
{
string jobIdValue = jobId.GetString();
}
if (root.TryGetProperty("status", out var status))
{
string statusValue = status.GetString();
}
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode}");
Console.WriteLine($"Response: {response.RawContent}");
}
```
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/csharp/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/csharp/task-management)
- [Authentication](https://docs.legnext.ai/sdk/csharp/authentication)
---
# Video Generation
_Generate and manipulate videos using C#/.NET SDK_
## Setup
```csharp
using System;
using System.Text.Json;
using System.Collections.Generic;
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();
```
## Text-to-Video
Generate videos from text descriptions:
```csharp
var request = new Dictionary
{
{ "text", "a cat walking in a garden" },
{ "videoType", 0 }, // 0=480p, 1=720p
{ "callback", "https://example.com/callback" }
};
var response = await videoApi.ApiV1VideoDiffusionPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Job ID: {jobId.GetString()}");
}
}
```
**With Additional Parameters:**
```csharp
var request = new Dictionary
{
{ "text", "sunset over ocean waves" },
{ "aspect_ratio", "16:9" },
{ "duration", 5 },
{ "videoType", 1 }, // 0=480p, 1=720p
{ "callback", "https://example.com/callback" }
};
```
**Image-to-Video (Animate Static Image):**
```csharp
var request = new Dictionary
{
{ "jobId", "original-image-job-id" },
{ "imageNo", 0 }, // Index of image to animate (0-3)
{ "videoType", 0 }, // 0=480p, 1=720p
{ "callback", "https://example.com/callback" }
};
var response = await videoApi.ApiV1VideoDiffusionPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Job ID: {jobId.GetString()}");
}
}
```
## Video Upscaling
Enhance video resolution:
```csharp
var request = new Dictionary
{
{ "jobId", "original-video-job-id" },
{ "videoNo", 0 }, // Index of video to upscale (0-3)
{ "callback", "https://example.com/callback" }
};
var response = await videoApi.ApiV1VideoUpscalePostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Upscale Job ID: {jobId.GetString()}");
}
}
```
## Extend Video
Extend video length:
```csharp
var request = new Dictionary
{
{ "jobId", "original-video-job-id" },
{ "videoNo", 1 }, // Index of video to extend (0-3)
{ "callback", "https://example.com/callback" }
};
var response = await videoApi.ApiV1ExtendVideoPostAsync(
new Option(apiKey),
request
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
if (jsonDoc.RootElement.TryGetProperty("job_id", out var jobId))
{
Console.WriteLine($"Extend Job ID: {jobId.GetString()}");
}
}
```
## Check Task Status
Monitor video generation progress:
```csharp
string jobId = "your-job-id";
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option(apiKey)
);
if (response.IsOk)
{
var jsonDoc = JsonDocument.Parse(response.RawContent);
var root = jsonDoc.RootElement;
if (root.TryGetProperty("status", out var status))
{
Console.WriteLine($"Status: {status.GetString()}");
}
if (root.TryGetProperty("output", out var output))
{
if (output.TryGetProperty("video_urls", out var videoUrls))
{
Console.WriteLine("Videos:");
foreach (var url in videoUrls.EnumerateArray())
{
Console.WriteLine($" - {url.GetString()}");
}
}
}
}
```
## Response Handling
All responses follow this pattern:
```csharp
var response = await videoApi.SomeMethodAsync(...);
if (response.IsOk)
{
// Parse the JSON response
var jsonDoc = JsonDocument.Parse(response.RawContent);
var root = jsonDoc.RootElement;
// Access properties
if (root.TryGetProperty("job_id", out var jobId))
{
string jobIdValue = jobId.GetString();
}
if (root.TryGetProperty("status", out var status))
{
string statusValue = status.GetString();
}
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode}");
Console.WriteLine($"Response: {response.RawContent}");
}
```
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/csharp/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/csharp/task-management)
- [Authentication](https://docs.legnext.ai/sdk/csharp/authentication)
---
# Task Management
_Handle async tasks and job status in C#/.NET SDK_
## 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
```csharp
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();
```
## Checking Task Status
Check the status of a job:
```csharp
string jobId = "your-job-id";
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option(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:
```csharp
public async Task WaitForTaskCompletionAsync(
string jobId,
int maxAttempts = 60,
int delaySeconds = 5)
{
for (int i = 0; i < maxAttempts; i++)
{
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option(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:
```csharp
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();
var videoApi = provider.GetRequiredService();
// Step 1: Generate image
var request = new Dictionary
{
{ "text", "a beautiful landscape" }
};
var generateResponse = await imageApi.ApiV1DiffusionPostAsync(
new Option(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(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:
```csharp
try
{
var response = await videoApi.ApiV1JobJobIdGetAsync(
jobId,
new Option(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
- [Image Generation](https://docs.legnext.ai/sdk/csharp/image-generation)
- [Video Generation](https://docs.legnext.ai/sdk/csharp/video-generation)
- [Authentication](https://docs.legnext.ai/sdk/csharp/authentication)
---
# Installation
_Install the Legnext Rust SDK_
## Requirements
- **Rust**: Version 1.70 or higher
- **Cargo**: Rust package manager
## Add to Cargo.toml
Add this dependency to your `Cargo.toml`:
```toml
[dependencies]
legnext-sdk = "1.0.0"
```
## Install via Cargo
```bash
cargo add legnext-sdk
```
## Verify Installation
```bash
cargo tree | grep legnext
```
## Build Your Project
```bash
cargo build
```
---
# Authentication
_Set up authentication for the Legnext Rust SDK_
## Get Your API Key
1. Visit [Legnext Dashboard](https://dashboard.legnext.ai)
2. Log in to your account
3. Navigate to **API Keys** section
4. Create a new API key
5. Copy and save it securely
## Using Your API Key
### Method 1: Direct Initialization
```rust
use legnext_rust_sdk::apis::configuration::Configuration;
use legnext_rust_sdk::apis::image_api;
#[tokio::main]
async fn main() {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = "your-api-key-here";
// Use api_key in function calls
}
```
### Method 2: Environment Variable (Recommended)
Set the environment variable:
```bash
# macOS/Linux
export LEGNEXT_API_KEY="your-api-key-here"
# Windows CMD
set LEGNEXT_API_KEY=your-api-key-here
# Windows PowerShell
$env:LEGNEXT_API_KEY="your-api-key-here"
```
Then in your code:
```rust
use std::env;
use legnext_rust_sdk::apis::configuration::Configuration;
#[tokio::main]
async fn main() {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = env::var("LEGNEXT_API_KEY")
.expect("LEGNEXT_API_KEY environment variable not set");
// Use api_key in function calls
}
```
### Method 3: Using dotenv Crate
Add to `Cargo.toml`:
```toml
[dependencies]
dotenv = "0.15"
legnext-rust-sdk = "1.0"
tokio = { version = "1", features = ["full"] }
```
Create `.env` file:
```env
LEGNEXT_API_KEY=your-api-key-here
LEGNEXT_BASE_URL=https://api.legnext.ai
```
In your code:
```rust
use dotenv::dotenv;
use std::env;
use legnext_rust_sdk::apis::configuration::Configuration;
#[tokio::main]
async fn main() {
dotenv().ok();
let mut config = Configuration::new();
config.base_path = env::var("LEGNEXT_BASE_URL")
.unwrap_or_else(|_| "https://api.legnext.ai".to_string());
let api_key = env::var("LEGNEXT_API_KEY")
.expect("LEGNEXT_API_KEY not found in environment");
// Use api_key in function calls
}
```
## Security Best Practices
⚠️ **Never hardcode API keys in your code**
✅ **Always use environment variables or .env files**
✅ **Add `.env` to `.gitignore`**
✅ **Use `expect()` or proper error handling for missing keys**
✅ **Rotate keys regularly and revoke compromised ones**
---
## Next Steps
- [Quick Start](https://docs.legnext.ai/sdk/rust/quickstart)
- [Image Generation API](https://docs.legnext.ai/sdk/rust/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/rust/video-generation)
---
# Quick Start
_Get started with the Legnext Rust SDK_
## 1. Add Dependency
Add to your `Cargo.toml`:
```toml
[dependencies]
legnext-rust-sdk = "1.0.0"
tokio = { version = "1", features = ["full"] }
```
## 2. Set API Key
```bash
export LEGNEXT_API_KEY="your-api-key"
```
## 3. Basic Example
```rust
use legnext_rust_sdk::apis::configuration::Configuration;
use legnext_rust_sdk::apis::image_api;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box> {
// Configure API client
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = env::var("LEGNEXT_API_KEY")?;
// Generate image
let mut request = std::collections::HashMap::new();
request.insert("text".to_string(), serde_json::json!("a beautiful sunset over mountains"));
match image_api::api_v1_diffusion_post(&config, Some(&api_key), Some(request)).await {
Ok(response) => {
println!("Response: {:?}", response);
}
Err(e) => {
eprintln!("Error: {:?}", e);
}
}
Ok(())
}
```
## 4. Check Task Status
```rust
use legnext_rust_sdk::apis::video_api;
let job_id = "your-job-id-here";
match video_api::api_v1_job_job_id_get(&config, &job_id, Some(&api_key)).await {
Ok(task_response) => {
if let Some(status) = task_response.status {
println!("Status: {}", status);
}
if let Some(output) = task_response.output {
if let Some(image_urls) = output.image_urls {
println!("Images: {:?}", image_urls);
}
}
}
Err(e) => {
eprintln!("Error: {:?}", e);
}
}
```
## Error Handling
```rust
match image_api::api_v1_diffusion_post(&config, Some(&api_key), Some(request)).await {
Ok(response) => {
// Handle success
println!("Success: {:?}", response);
}
Err(e) => {
eprintln!("Error: {:?}", e);
}
}
```
## Async/Await
All API calls are async and require an async runtime like Tokio:
```toml
[dependencies]
tokio = { version = "1", features = ["full"] }
```
## Available APIs
- `image_api` - Text to image, variations, upscaling, editing
- `video_api` - Video generation, upscaling, and task status
- `account_management_api` - Account balance and information
---
# Image Generation
_Image generation API reference for Rust SDK_
## api_v1_diffusion_post()
Create a new text-to-image generation task.
```rust
use legnext_rust_sdk::{
apis::configuration::Configuration,
apis::image_api,
};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = "your-api-key-here";
let mut body = HashMap::new();
body.insert("text".to_string(), "a serene mountain landscape at sunset");
body.insert("callback".to_string(), "https://your-domain.com/webhook");
let response = image_api::api_v1_diffusion_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
println!("Job ID: {:?}", response.job_id);
Ok(())
}
```
**Parameters:**
- `configuration` (&Configuration): API configuration
- `x_api_key` (Option<&str>): Your API key
- `body` (Option): Request body with:
- `text` (String): Text prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL
**Returns:** `Result` with `job_id` and `status`
---
## api_v1_vary_post()
Create variations of a generated image.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("type", 1); // 0=Subtle, 1=Strong
body.insert("remixPrompt", "add more clouds");
body.insert("callback", "https://your-domain.com/webhook");
let response = image_api::api_v1_vary_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_upscale_post()
Upscale a generated image.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("type", 1); // 0=Subtle, 1=Creative
body.insert("callback", "https://your-domain.com/webhook");
let response = image_api::api_v1_upscale_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_reroll_post()
Regenerate with the same prompt.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_reroll_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_blend_post()
Blend 2-5 images together.
```rust
let mut body = HashMap::new();
body.insert("imgUrls", vec![
"https://example.com/image1.png",
"https://example.com/image2.png"
]);
body.insert("aspect_ratio", "1:1");
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_blend_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_describe_post()
Generate text descriptions from an image.
```rust
let mut body = HashMap::new();
body.insert("imgUrl", "https://example.com/image.png");
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_describe_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_edit_post()
Edit an image with text description.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("canvas", 512); // Required: canvas size
body.insert("imgPos", "center"); // Required: image position
body.insert("remixPrompt", "change the sky to sunset colors");
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_edit_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_inpaint_post()
Fill masked regions in an image.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("remixPrompt", "fill with forest landscape");
body.insert("mask", serde_json::json!({
"type": "url",
"url": "https://example.com/mask.png"
}));
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_inpaint_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_outpaint_post()
Extend image boundaries.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("scale", 1.5);
body.insert("remixPrompt", "extend with matching landscape");
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_outpaint_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_pan_post()
Create panoramic or panned views.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("direction", 3); // 0=Down, 1=Right, 2=Up, 3=Left
body.insert("scale", 1.5); // Range: 1.1-3.0
body.insert("remixPrompt", "add more elements in the direction");
body.insert("callback", "https://your-domain.com/webhook");
image_api::api_v1_pan_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
---
## api_v1_remix_post()
Create a remix of an image with different settings.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-job-id");
body.insert("imageNo", 0);
body.insert("mode", 0); // 0=Strong, 1=Subtle
body.insert("remixPrompt", "dramatic lighting and vibrant colors");
body.insert("callback", "https://your-domain.com/webhook");
let response = image_api::api_v1_remix_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
println!("Remix Job ID: {:?}", response.job_id);
```
---
## api_v1_shorten_post()
Optimize and simplify prompts.
```rust
let mut body = HashMap::new();
body.insert("prompt", "your very long and detailed prompt here...");
body.insert("callback", "https://your-domain.com/webhook");
let response = image_api::api_v1_shorten_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
println!("Optimized prompt: {:?}", response.shortened_prompt);
```
---
## Next Steps
- [Video Generation](https://docs.legnext.ai/sdk/rust/video-generation)
- [Task Management](https://docs.legnext.ai/sdk/rust/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/rust/quickstart)
---
# Video Generation
_Video generation API reference for Rust SDK_
## api_v1_video_diffusion_post()
Generate a video from text prompt, with optional image URL or image animation.
```rust
use legnext_rust_sdk::{
apis::configuration::Configuration,
apis::video_api,
};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = "your-api-key-here";
// Generate from text only
let mut body = HashMap::new();
body.insert("prompt", "a flowing river through mountains");
body.insert("videoType", 1); // 0=480p, 1=720p
body.insert("callback", "https://your-domain.com/webhook");
let response = video_api::api_v1_video_diffusion_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
println!("Job ID: {:?}", response.job_id);
Ok(())
}
```
**Generate from Image URL:**
```rust
// Generate from image URL
let mut body = HashMap::new();
body.insert(
"prompt",
"https://example.com/image.png a flowing river through mountains"
);
body.insert("videoType", 1); // 0=480p, 1=720p
body.insert("callback", "https://your-domain.com/webhook");
let response = video_api::api_v1_video_diffusion_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
**Animate Image from Previous Job:**
```rust
// Animate image from previous generation job
let mut body = HashMap::new();
body.insert("prompt", "a flowing river through mountains");
body.insert("jobId", "original-image-job-id");
body.insert("imageNo", 0); // Image index from job
body.insert("videoType", 1); // 0=480p, 1=720p
body.insert("callback", "https://your-domain.com/webhook");
let response = video_api::api_v1_video_diffusion_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
```
**Parameters:**
- `configuration` (&Configuration): API configuration
- `x_api_key` (Option<&str>): Your API key
- `body` (Option): Request body with:
- `prompt` (String): Video prompt or "[image_url] prompt text" (1-8192 characters)
- `jobId` (String, optional): Original image job ID for animation mode
- `imageNo` (Integer, optional): Image index when using jobId (0-3)
- `videoType` (Integer, optional): Quality (0=480p, 1=720p)
- `callback` (String, optional): Webhook URL
**Returns:** `Result` with `job_id` and `status`
---
## api_v1_extend_video_post()
Extend an existing video.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-video-job-id");
body.insert("videoNo", 0);
body.insert("prompt", "continue with dramatic lighting");
body.insert("callback", "https://your-domain.com/webhook");
let response = video_api::api_v1_extend_video_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
println!("Extension Job ID: {:?}", response.job_id);
```
**Parameters:**
- `configuration` (&Configuration): API configuration
- `x_api_key` (Option<&str>): Your API key
- `body` (Option): Request body with:
- `jobId` (String): Original video task ID
- `videoNo` (Integer): Video index (0-3)
- `prompt` (String, optional): Extension prompt (1-8192 characters)
- `callback` (String, optional): Webhook URL
**Returns:** `Result` with `job_id` and `status`
---
## api_v1_video_upscale_post()
Upscale video to higher resolution.
```rust
let mut body = HashMap::new();
body.insert("jobId", "original-video-job-id");
body.insert("videoNo", 0);
body.insert("callback", "https://your-domain.com/webhook");
let response = video_api::api_v1_video_upscale_post(
&config,
Some(api_key),
Some(serde_json::to_value(body)?),
).await?;
println!("Upscale Job ID: {:?}", response.job_id);
```
**Parameters:**
- `configuration` (&Configuration): API configuration
- `x_api_key` (Option<&str>): Your API key
- `body` (Option): Request body with:
- `jobId` (String): Original video task ID
- `videoNo` (Integer): Video index (0-3)
- `callback` (String, optional): Webhook URL
**Returns:** `Result` with `job_id` and `status`
---
## Complete Example
```rust
use legnext_rust_sdk::{
apis::configuration::Configuration,
apis::video_api,
};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = std::env::var("LEGNEXT_API_KEY")
.expect("LEGNEXT_API_KEY environment variable not set");
// Step 1: Generate video
let mut body = HashMap::new();
body.insert("prompt", "a beautiful sunset over the ocean");
body.insert("videoType", 1);
let response = video_api::api_v1_video_diffusion_post(
&config,
Some(&api_key),
Some(serde_json::to_value(body)?),
).await?;
let job_id = response.job_id.unwrap();
println!("Video generation started: {}", job_id);
// Step 2: Wait for completion (see Task Management docs)
// ...
// Step 3: Extend the video
let mut extend_body = HashMap::new();
extend_body.insert("jobId", &job_id);
extend_body.insert("videoNo", 0);
extend_body.insert("prompt", "continue with dramatic clouds");
let extend_response = video_api::api_v1_extend_video_post(
&config,
Some(&api_key),
Some(serde_json::to_value(extend_body)?),
).await?;
println!("Video extension started: {:?}", extend_response.job_id);
Ok(())
}
```
---
## Next Steps
- [Image Generation](https://docs.legnext.ai/sdk/rust/image-generation)
- [Task Management](https://docs.legnext.ai/sdk/rust/task-management)
- [Quick Start](https://docs.legnext.ai/sdk/rust/quickstart)
---
# Task Management
_Task status, polling, and error handling for Rust SDK_
## api_v1_job_job_id_get()
Get current task status:
```rust
use legnext_rust_sdk::{
apis::configuration::Configuration,
apis::image_api,
};
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = "your-api-key-here";
let job_id = "job-123";
let task = image_api::api_v1_job_job_id_get(
&config,
job_id,
Some(api_key),
).await?;
println!("Status: {:?}", task.status);
println!("Progress: {}%", task.progress.unwrap_or(0));
if task.status == Some("completed".to_string()) {
println!("Result: {:?}", task.output);
}
Ok(())
}
```
---
## Polling for Completion
Wait for task completion with polling:
```rust
use legnext_rust_sdk::{
apis::configuration::Configuration,
apis::image_api,
};
use std::time::Duration;
use tokio::time::sleep;
async fn wait_for_completion(
config: &Configuration,
job_id: &str,
api_key: &str,
timeout_seconds: u64,
poll_interval_seconds: u64,
) -> Result> {
let start_time = std::time::Instant::now();
let timeout = Duration::from_secs(timeout_seconds);
loop {
let task = image_api::api_v1_job_job_id_get(
config,
job_id,
Some(api_key),
).await?;
println!("Current status: {:?}", task.status);
if task.status == Some("completed".to_string()) {
println!("Task completed successfully!");
println!("Output: {:?}", task.output);
return Ok(task.output.unwrap_or_default());
} else if task.status == Some("failed".to_string()) {
return Err(format!("Task failed: {:?}", task.error).into());
}
// Check timeout
if start_time.elapsed() > timeout {
return Err(format!("Task timeout after {} seconds", timeout_seconds).into());
}
// Wait before next poll
sleep(Duration::from_secs(poll_interval_seconds)).await;
}
}
```
**Usage:**
```rust
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = std::env::var("LEGNEXT_API_KEY")?;
let job_id = "job-123";
match wait_for_completion(&config, job_id, &api_key, 300, 3).await {
Ok(result) => println!("Final result: {:?}", result),
Err(e) => eprintln!("Error: {}", e),
}
Ok(())
}
```
---
## Complete Example with Error Handling
```rust
use legnext_rust_sdk::{
apis::configuration::Configuration,
apis::image_api,
};
use std::collections::HashMap;
use std::time::Duration;
use tokio::time::sleep;
async fn wait_for_completion(
config: &Configuration,
job_id: &str,
api_key: &str,
timeout_seconds: u64,
poll_interval_seconds: u64,
) -> Result> {
let start_time = std::time::Instant::now();
let timeout = Duration::from_secs(timeout_seconds);
loop {
let task = image_api::api_v1_job_job_id_get(
config,
job_id,
Some(api_key),
).await?;
if task.status == Some("completed".to_string()) {
return Ok(task.output.unwrap_or_default());
} else if task.status == Some("failed".to_string()) {
return Err(format!("Task failed: {:?}", task.error).into());
}
if start_time.elapsed() > timeout {
return Err(format!("Task timeout after {} seconds", timeout_seconds).into());
}
sleep(Duration::from_secs(poll_interval_seconds)).await;
}
}
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = std::env::var("LEGNEXT_API_KEY")
.expect("LEGNEXT_API_KEY environment variable not set");
// Step 1: Start generation
let mut body = HashMap::new();
body.insert("text".to_string(), "a beautiful sunset over mountains");
let response = image_api::api_v1_diffusion_post(
&config,
Some(&api_key),
Some(serde_json::to_value(body)?),
).await?;
let job_id = response.job_id.ok_or("No job_id in response")?;
println!("Job started: {}", job_id);
// Step 2: Poll for completion
let result = wait_for_completion(&config, &job_id, &api_key, 600, 3).await?;
// Step 3: Get final result
println!("Image URLs: {:?}", result);
Ok(())
}
```
---
## Error Handling
**HTTP Error Handling:**
The Rust SDK returns `Result` types. Handle errors using pattern matching:
```rust
use legnext_rust_sdk::apis::Error;
match image_api::api_v1_diffusion_post(&config, Some(&api_key), Some(body)).await {
Ok(response) => {
println!("Success: {:?}", response);
}
Err(Error::ResponseError(ref content)) => {
match content.status {
400 => eprintln!("Validation error: {:?}", content.content),
401 => eprintln!("Authentication error: Invalid API key"),
404 => eprintln!("Resource not found"),
429 => eprintln!("Rate limit exceeded. Please retry later."),
500 | 502 | 503 => eprintln!("Server error: {:?}", content.content),
_ => eprintln!("API error ({}): {:?}", content.status, content.content),
}
}
Err(e) => eprintln!("Unexpected error: {:?}", e),
}
```
**Common HTTP Status Codes:**
| Status Code | Description | Action |
|-------------|-------------|--------|
| 400 | Invalid request parameters | Check request body format |
| 401 | Invalid API key | Verify API key is correct |
| 404 | Resource not found | Check job ID exists |
| 429 | Rate limit exceeded | Wait and retry with backoff |
| 500/502/503 | Server error | Retry with exponential backoff |
**Retry Logic with Exponential Backoff:**
```rust
use std::time::Duration;
use tokio::time::sleep;
async fn call_with_retry(
api_call: F,
max_retries: u32,
) -> Result>
where
F: Fn() -> futures::future::BoxFuture<'static, Result>,
{
for i in 0..max_retries {
match api_call().await {
Ok(result) => return Ok(result),
Err(Error::ResponseError(ref content)) => {
if content.status == 429 {
// Rate limited - wait and retry
sleep(Duration::from_secs(5)).await;
continue;
} else if content.status >= 500 {
// Server error - exponential backoff
let delay = Duration::from_secs(2_u64.pow(i));
sleep(delay).await;
if i == max_retries - 1 {
return Err(Box::new(content.clone()));
}
continue;
} else {
// Other errors - don't retry
return Err(Box::new(content.clone()));
}
}
Err(e) => return Err(Box::new(e)),
}
}
Err("Max retries exceeded".into())
}
// Usage
let result = call_with_retry(
|| Box::pin(image_api::api_v1_diffusion_post(&config, Some(&api_key), Some(body.clone()))),
3,
).await?;
```
---
## Concurrent Operations with Tokio
For processing multiple tasks concurrently:
```rust
use tokio::try_join;
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut config = Configuration::new();
config.base_path = "https://api.legnext.ai".to_string();
let api_key = std::env::var("LEGNEXT_API_KEY")?;
let prompts = vec!["sunset", "mountains", "ocean"];
// Start all generations concurrently
let mut handles = vec![];
for prompt in prompts {
let config_clone = config.clone();
let api_key_clone = api_key.clone();
let prompt_clone = prompt.to_string();
let handle = tokio::spawn(async move {
let mut body = HashMap::new();
body.insert("text".to_string(), prompt_clone.clone());
let response = image_api::api_v1_diffusion_post(
&config_clone,
Some(&api_key_clone),
Some(serde_json::to_value(body)?),
).await?;
let job_id = response.job_id.ok_or("No job_id")?;
// Wait for completion
let result = wait_for_completion(
&config_clone,
&job_id,
&api_key_clone,
600,
3,
).await?;
Ok::<_, Box>(result)
});
handles.push(handle);
}
// Wait for all tasks to complete
for handle in handles {
match handle.await {
Ok(Ok(result)) => println!("Image generated: {:?}", result),
Ok(Err(e)) => eprintln!("Task error: {}", e),
Err(e) => eprintln!("Join error: {}", e),
}
}
Ok(())
}
```
---
## Progress Callbacks
```rust
use std::sync::Arc;
use tokio::sync::Mutex;
async fn wait_for_completion_with_progress(
config: &Configuration,
job_id: &str,
api_key: &str,
on_progress: F,
timeout_seconds: u64,
poll_interval_seconds: u64,
) -> Result>
where
F: Fn(i32, &str),
{
let start_time = std::time::Instant::now();
let timeout = Duration::from_secs(timeout_seconds);
loop {
let task = image_api::api_v1_job_job_id_get(
config,
job_id,
Some(api_key),
).await?;
// Call progress callback
on_progress(
task.progress.unwrap_or(0),
task.status.as_deref().unwrap_or("unknown"),
);
if task.status == Some("completed".to_string()) {
return Ok(task.output.unwrap_or_default());
} else if task.status == Some("failed".to_string()) {
return Err(format!("Task failed: {:?}", task.error).into());
}
if start_time.elapsed() > timeout {
return Err(format!("Task timeout after {} seconds", timeout_seconds).into());
}
sleep(Duration::from_secs(poll_interval_seconds)).await;
}
}
// Usage
let result = wait_for_completion_with_progress(
&config,
&job_id,
&api_key,
|progress, status| {
println!("Progress: {}% - Status: {}", progress, status);
},
600,
3,
).await?;
```
---
## Learn More
- [Image Generation API](https://docs.legnext.ai/sdk/rust/image-generation)
- [Video Generation API](https://docs.legnext.ai/sdk/rust/video-generation)
- [Quick Start](https://docs.legnext.ai/sdk/rust/quickstart)
---
# Integrations Overview
_Connect Legnext AI API with your favorite automation platforms_
Integrate Legnext AI API with popular automation and workflow platforms to create powerful image and video generation workflows without writing code.
## Available Integrations
- **n8n**: } href="/integrations/n8n"> Connect Legnext with n8n to build automated workflows for image and video generation. Perfect for creating custom automation pipelines.
- **Postman**: } href="/integrations/postman"> Test and explore Legnext AI API using our official Postman collection. Perfect for API testing and development.
- **Make**: } href="/integrations/make"> Build visual automation workflows with Make (formerly Integromat). Connect with 1000+ apps without coding.
- **n8n**
- **Postman**
- **Make**
### Coming Soon
We're working on official integrations for:
- **Zapier** - Connect with 5000+ apps
Stay tuned for updates!
---
## Benefits of Platform Integrations
- **No Code Required** - Build powerful workflows with visual editors
- **Connect Multiple Services** - Combine Legnext with other tools in your stack
- **Automate Workflows** - Trigger image generation from various events
- **Scale Easily** - Handle bulk operations without custom code
---
## Request an Integration
Don't see the integration you need? We're always looking to expand our ecosystem.
[Request an integration](mailto:support@legnext.ai?subject=Integration%20Request) and let us know what platform you'd like to see next.
## Need Help?
If you need assistance with integrations, reach out to our support team at support@legnext.ai
---
# n8n Integration
_Connect Legnext AI API with n8n to build automated workflows_
## Overview
n8n is a powerful workflow automation tool that allows you to connect various services and APIs. By integrating Legnext AI API with n8n, you can:
- **Automate Image Generation** - Trigger image creation based on events from other services
- **Build Complex Workflows** - Chain multiple operations together
- **Process Data at Scale** - Handle bulk image generation tasks
- **No Coding Required** - Use visual workflow editor
## Key Features
- **Visual Workflow Builder**: Create complex automations with a drag-and-drop interface.
- **Advanced Logic**: Use if-statements, loops, and merges to build sophisticated pipelines.
- **Self-Hosted Option**: Run n8n on your own infrastructure for complete data control.
- **Community Nodes**: Access a wide range of community-built nodes and workflows.
## Video Tutorial
Watch this tutorial to learn how to set up Legnext with n8n:
## Getting Started
### Prerequisites
- An n8n instance (self-hosted or cloud)
- A Legnext API key ([Get one here](https://legnext.ai))
- Basic understanding of workflow automation
### Installation
1. **Download the Preset Workflow**
[Download Preset Workflow](https://raw.githubusercontent.com/leggiemint/legnext-resources/refs/heads/main/example_workflow.json)
2. **Import into n8n**
- Open your n8n instance
- Go to Workflows
- Click "Import from File"
- Select the downloaded JSON file
3. **Configure API Credentials**
- Add your Legnext API key to the HTTP Request nodes
- Test the connection
## Use Cases
### Automated Social Media Content
Create a workflow that generates images based on trending topics and posts them to social media platforms.
### E-commerce Product Images
Generate product images automatically when new items are added to your inventory system.
### Content Pipeline
Build a content creation pipeline that generates images for blog posts, newsletters, or marketing materials.
### Scheduled Image Generation
Set up scheduled workflows to generate images at specific times or intervals.
## Best Practices
- **Error Handling** - Add error handling nodes to manage API failures gracefully
- **Rate Limiting** - Be mindful of API rate limits when processing large batches
- **Webhook Configuration** - Use webhooks for async operations to avoid timeout issues
- **Data Validation** - Validate input data before sending to the API
## Troubleshooting
### Common Issues
**Connection Timeout**
- Use webhook callbacks for long-running operations
- Increase timeout settings in n8n HTTP Request node
**API Key Errors**
- Verify your API key is correctly configured
- Check that the key has proper permissions
**Invalid Parameters**
- Review the API documentation for correct parameter formats
- Validate your input data before sending requests
## Need Help?
If you need assistance with n8n integration, reach out to our support team at support@legnext.ai
---
# Postman Collection
_Test and explore Legnext AI API using our official Postman collection_
## Quick Start
Get started with our pre-configured Postman collection. Click the button below to fork the collection to your workspace:
[Run in Postman](https://www.postman.com/legnext-ai/workspace/legnext-ai-s-workspace/collection/49973316-23452527-b0dc-420a-b21c-cba1d8d5d87a?action=share&source=copy-link&creator=49973316)
## What's Included
Our Postman collection includes ready-to-use requests for:
### Image Generation
- **Text-to-Image** - Generate images from text descriptions
- **Image-to-Image** - Transform existing images
- **Upscale** - Enhance image resolution
- **Variation** - Create variations of existing images
### Video Generation
- **Video Diffusion** - Generate videos from images or text
- **Video Extend** - Extend video duration
- **Video Upscale** - Enhance video quality
### Task Management
- **Get Task Status** - Check task progress
- **Get Task Result** - Retrieve completed results
- **Cancel Task** - Cancel running tasks
### Account Management
- **Get Balance** - Check your account balance and usage
## Prerequisites
- A Postman account (free or paid)
- Postman Desktop App or Web Client
- A Legnext API key ([Get one here](https://legnext.ai))
## Setup Instructions
### 1. Fork the Collection
Click the "Run in Postman" button above to fork the collection to your workspace.
### 2. Configure API Key
After importing the collection:
1. Open the collection in Postman
2. Go to the "Variables" tab
3. Set the `api_key` variable to your Legnext API key
4. Save the changes
### 3. Start Testing
Select any request from the collection and click "Send" to test the API.
## Collection Features
### Environment Variables
The collection uses variables for easy configuration:
- `base_url` - API base URL (pre-configured)
- `api_key` - Your API key (you need to set this)
- `job_id` - Automatically saved from responses for chaining requests
### Pre-Request Scripts
Some requests include pre-request scripts to:
- Validate required variables
- Generate dynamic data
- Set up request dependencies
### Test Scripts
Responses include test scripts that:
- Validate response status
- Extract and save job IDs
- Check response structure
## Use Cases
### API Exploration
Quickly explore all available endpoints and understand request/response formats without writing code.
### Development Testing
Test API integration during development with easy-to-modify requests and instant feedback.
### Documentation Reference
Use the collection as a living documentation reference with real examples for all endpoints.
### Team Collaboration
Share the collection with your team to ensure everyone uses consistent API patterns.
## Tips and Best Practices
### Save Your Responses
Use Postman's "Save Response" feature to create examples for your team.
### Use Environments
Create different environments (development, staging, production) with different API keys.
### Organize with Folders
The collection is organized by feature - use this structure to quickly find what you need.
### Chain Requests
Use the saved `job_id` variable to chain related requests together (e.g., generate → upscale → get result).
## Troubleshooting
### "Invalid API Key" Error
Make sure you've set your API key in the collection variables:
1. Click on the collection name
2. Go to "Variables" tab
3. Set the `api_key` value
4. Save
### "Request Timeout" Error
Some operations (like video generation) take time. Use the task status endpoint to poll for results instead of waiting for the initial request.
### Variables Not Saving
Make sure you're saving the collection after making changes to variables.
## Public Workspace
Visit our public Postman workspace to explore more:
[View Legnext AI Workspace](https://www.postman.com/legnext-ai/workspace/legnext-ai-s-workspace/collection/49973316-23452527-b0dc-420a-b21c-cba1d8d5d87a?action=share&source=copy-link&creator=49973316)
## Need Help?
If you need assistance with the Postman collection, reach out to our support team at support@legnext.ai
---
# Make Integration
_Connect Legnext AI API with Make (formerly Integromat) to build visual automation workflows_
## Overview
Make is a visual platform that lets you design, build, and automate workflows by connecting apps and services. By integrating Legnext AI API with Make, you can:
- **Visual Workflow Builder** - Create complex automations with drag-and-drop interface
- **Connect 1000+ Apps** - Integrate with popular tools like Google Drive, Slack, Airtable, and more
- **Advanced Logic** - Use routers, filters, and conditional logic in your workflows
- **Real-time Processing** - Process images and videos as events happen
- **No Coding Required** - Build powerful automations without technical expertise
## Getting Started
### Join Our Make Organization
Get access to pre-built Legnext templates and modules:
[Join Make Organization](https://www.make.com/en/hq/app-invitation/1ff92bec923a3c4561e85cf2da047c12)
### Prerequisites
- A Make account (free or paid)
- A Legnext API key ([Get one here](https://legnext.ai))
- Basic understanding of workflow automation
### Setup Steps
1. **Join the Organization**
- Click the button above to accept the invitation
- Log in to your Make account or create a new one
2. **Access Legnext Templates**
- Browse pre-built scenarios in the organization
- Clone templates to your workspace
3. **Configure API Connection**
- Add your Legnext API key to HTTP modules
- Test the connection
4. **Customize Your Workflow**
- Modify the scenario to fit your needs
- Add additional apps and logic
## Use Cases
### Automated Content Creation
Create a workflow that monitors your content calendar and automatically generates images when new content is scheduled.
**Example Flow:**
```
Google Sheets (New Row) → Legnext (Generate Image) → Google Drive (Save File) → Slack (Send Notification)
```
### Social Media Automation
Generate and post images to multiple social media platforms based on triggers.
**Example Flow:**
```
RSS Feed → Legnext (Generate Image) → Dropbox (Save) → Twitter/Instagram (Post)
```
### E-commerce Product Images
Automatically generate product images when new items are added to your store.
**Example Flow:**
```
Shopify (New Product) → Legnext (Generate Image) → Shopify (Update Product Image)
```
### Email Marketing Campaigns
Create personalized images for email campaigns based on customer data.
**Example Flow:**
```
Mailchimp (New Campaign) → Airtable (Get Data) → Legnext (Generate Images) → Mailchimp (Add Images)
```
### Video Content Pipeline
Build automated video generation workflows for marketing or social media.
**Example Flow:**
```
Trello (Card Moved) → Legnext (Generate Video) → Vimeo (Upload) → Email (Send Review Link)
```
## Key Features
### HTTP Modules
Use Make's HTTP modules to interact with the Legnext API:
- **HTTP Request** - Make API calls to Legnext endpoints
- **Webhooks** - Receive completion notifications from Legnext
- **JSON Parsing** - Process API responses
### Data Mapping
Map data between apps using Make's intuitive interface:
- Transform text data into image prompts
- Extract job IDs from responses
- Format URLs and parameters
### Error Handling
Build robust workflows with Make's error handling:
- **Error Handler Routes** - Define fallback actions
- **Retry Logic** - Automatically retry failed requests
- **Notifications** - Get alerted when errors occur
### Scheduling
Run workflows on schedules:
- **Interval Scheduling** - Run every N minutes/hours
- **Specific Times** - Run at exact times daily/weekly
- **Custom Cron** - Advanced scheduling options
## Available Legnext Operations
### Image Generation
- Text-to-Image
- Image-to-Image
- Image Upscaling
- Image Variations
### Video Generation
- Video Diffusion
- Video Extension
- Video Upscaling
### Task Management
- Get Task Status
- Get Task Result
- Cancel Task
### Account
- Get Balance
## Best Practices
### Use Webhooks for Long Operations
For video generation and other long-running tasks:
1. Send the initial API request with a webhook URL
2. Use Make's webhook to receive the completion notification
3. Process the result in a separate scenario
### Handle Rate Limits
- Add delay modules between bulk operations
- Use Make's scheduling to spread out requests
- Monitor your API usage in the Legnext dashboard
### Store Job IDs
- Use data stores to track job IDs
- Link generation and result retrieval operations
- Maintain history of completed tasks
### Test Thoroughly
- Use Make's test execution feature
- Verify all API connections before going live
- Set up error notifications
## Example Scenarios
### Basic Image Generation
**Trigger:** Google Form submission
**Actions:**
1. Parse form response
2. Call Legnext text-to-image API
3. Wait for completion (webhook or polling)
4. Save image to Google Drive
5. Send email with image link
### Batch Image Processing
**Trigger:** New file in Dropbox folder
**Actions:**
1. Get file URL from Dropbox
2. Call Legnext image-to-image API
3. Apply style transformation
4. Save result to different folder
5. Update Airtable with status
### Video Generation Pipeline
**Trigger:** Scheduled (daily at 9 AM)
**Actions:**
1. Get content from CMS (e.g., WordPress)
2. Generate video using Legnext
3. Monitor task status
4. Upload to YouTube when ready
5. Post announcement on social media
## Troubleshooting
### Connection Issues
**Problem:** Can't connect to Legnext API
**Solution:**
- Verify your API key is correct
- Check that you're using the correct endpoint URL
- Ensure your Make plan supports HTTP requests
### Timeout Errors
**Problem:** Scenario times out waiting for response
**Solution:**
- Use webhook callbacks instead of waiting
- Split generation and retrieval into separate scenarios
- Use Make's resume feature for long-running operations
### Data Mapping Errors
**Problem:** Data not mapping correctly between modules
**Solution:**
- Use Make's mapping panel to visualize data structure
- Test with sample data first
- Check JSON response format in API documentation
### Webhook Not Triggering
**Problem:** Not receiving webhook notifications
**Solution:**
- Verify webhook URL is correct in API request
- Check Make webhook is active and listening
- Test webhook with Make's "Determine data structure" feature
## Resources
- [Make Documentation](https://www.make.com/en/help/getting-started)
- [Legnext API Documentation](https://docs.legnext.ai/api-reference)
- [Community Forum](https://community.make.com)
## Need Help?
If you need assistance with Make integration, reach out to our support team at support@legnext.ai
---
# Changelog
_Track updates, new features, and improvements to the Legnext AI API_
### April 25, 2026 — _New Feature_
#### Midjourney V8.1 Support
- **V8.1 Model**: Add `--v 8.1` to your prompt to use Midjourney's latest alpha model — HD is now the default output, with ~40% faster generation than V8 HD
- **HD by default, no premium**: V8.1 produces native 2K images at the same cost as V8 SD (1x credits). The 4x premium that applied to V8 `--hd` does **not** apply to V8.1
- **Image prompts and image weights restored**: V8.1 supports image URLs in prompts and the `--iw` parameter for image weighting
- **Prompt Shortener**: Prompts that exceed length limits are automatically shortened by Midjourney
- **Improved Describe**: V8.1 produces longer, more detailed prompt descriptions
- **Subscription gate**: V8.1 requires a Pro (Developer) subscription or higher, same as V8
- **Removed in V8.1**: `--q` / `--quality`, `--cref` / `--cw`, `--oref` / `--ow`, and `--no` (negative prompt) are no longer supported. Requests containing these flags will be rejected with a clear error
- **V8.0 deprecation**: Midjourney plans to sunset V8.0 approximately 2 weeks after V8.1 stabilizes. Migrate `--v 8` prompts to `--v 8.1` to avoid disruption
- **Same endpoints**: V8.1 uses the existing `/v1/diffusion`, `/v1/variation`, `/v1/reroll`, `/v1/remix`, `/v1/blend`, and `/v1/video-diffusion` endpoints — no integration changes required
### April 3, 2026 — _New Feature_
#### Midjourney V8 Support
- **V8 Model**: Add `--v 8` to your prompt to use Midjourney's latest model — ~5x faster generation, native 2K HD resolution, dramatically improved text rendering, and accurate anatomy
- **Native 2K with --hd**: V8 renders natively at 2K resolution. No upscale step needed. Use `--hd` for high-resolution output (4x credit cost)
- **New --oref parameter**: Omni Reference replaces `--cref` in V8, handling both person likeness and object form in a single parameter
- **Enhanced coherence with --q 4**: New quality mode for complex scenes with many elements (4x credit cost)
- **V8 Blend**: Blend endpoint now uses V8 natively for improved results
- **Full follow-up support**: Variation, reroll, remix, and animate all work on V8-generated images
- **Backward compatible**: Your existing V7 personalization profiles and style references work in V8
### December 17, 2025 — _New Feature_
#### Topaz Integration Released
- **[Topaz Upscale API](https://docs.legnext.ai/api-reference/enhancement/topaz-upscale)**: New `/v1/enhance-upscale` endpoint for ultra-high resolution image enhancement (up to 12K) using Topaz Labs AI technology
- **Improved Parameter Organization**: Clear input method options (direct image URL or Midjourney task) with intuitive common parameters grouping
- **Transparent Pricing**: Enhanced resolution options table with cost breakdown and recommended use cases for each resolution tier
### October 20, 2025 — _SDK Release_
#### Python SDK Released
- **Official Python SDK**: Available on PyPI as `legnext`
- **Complete Documentation**: New SDKs tab with guides, API reference, and examples
- **Features**: Type hints, async support, webhook callbacks, error handling
### October 10, 2025 — _New releases_
#### New API endpoints
- **/blend**: Easily blend images together using Midjourney's /blend command
- **/describe**: Writes four example prompts based on an image you upload
- **/shorten**: Submit a long prompt and receive suggestions on how to make it more concise
### October 9, 2025 — _Improvements_
#### Response structure enhancements
- **4-grid image display**: Enhanced response structure to support 4-grid image display for /imagine tasks, providing better visualization of generated image variations
#### Service optimization
- **Temporary API endpoint suspension**: The following endpoints are temporarily paused:
- /upload-paint
- /retexture
- /remove-background
- /enhance
These endpoints will be restored promptly after optimization is complete.
---