Skip to main content
POST
/
api
/
undress
/
generate
AI Undress
curl --request POST \
  --url https://api.example.com/api/undress/generate \
  --header 'Content-Type: application/json' \
  --data '
{
  "quality": "<string>"
}
'
{
  "success": true,
  "resultUrl": "<string>",
  "generationId": 123,
  "quality": "<string>",
  "provider": "<string>",
  "processingTimeMs": 123,
  "creditsCharged": 123,
  "creditsRemaining": 123,
  "error": "<string>",
  "code": "<string>"
}
This endpoint generates AI-transformed images using advanced image editing models. It supports two quality tiers with automatic provider selection and fallback logic.

Authentication

Requires user authentication and explicit consent acceptance.
Mandatory Consent: Users must accept the AI Undress policy (version 1) via /api/undress/consent before using this endpoint. Requests without accepted consent will be rejected with 403 status.

Credit Cost

Quality Tiers:
QualityProviderFeature KeyDefault Cost
LowFreepik Seedream 4.5 Editai_undress_low25 credits
HighxAI Grok Image Proai_undress_high45 credits
Credits are deducted upfront before generation starts. Automatic refunds are issued on generation failures.

Rate Limits

  • Daily Limit: 30 generations per user per 24-hour period
  • Concurrent Limit: 3 active generations per user
  • Reset: Daily limit resets at midnight UTC

Request

image
file
required
The image file to transform (multipart/form-data upload).Supported Formats:
  • JPEG (image/jpeg, image/jpg)
  • PNG (image/png)
  • WebP (image/webp)
Size Limit: 25MB maximum
quality
string
required
The quality tier to use:
  • low - Freepik Seedream 4.5 Edit (25 credits)
  • high - xAI Grok Image Pro (45 credits)

Request Example (multipart/form-data)

curl -X POST https://api.joip.io/api/undress/generate \
  -H "Cookie: connect.sid=..." \
  -F "[email protected]" \
  -F "quality=low"

Response

success
boolean
Whether the generation succeeded.
resultUrl
string
The URL of the generated image (Supabase storage).
generationId
number
Database ID for the generation record.
quality
string
The quality tier used (low or high).
provider
string
The actual provider used:
  • freepik - Freepik Seedream 4.5 Edit
  • xai - xAI Grok Image API
processingTimeMs
number
Time taken for generation in milliseconds.
creditsCharged
number
Number of credits deducted for this generation.
creditsRemaining
number
User’s remaining credit balance after deduction.

Success Response

{
  "success": true,
  "resultUrl": "https://storage.supabase.co/v1/object/public/user-media/users/abc123/undress/result/result_1234567890_output.jpg",
  "generationId": 42,
  "quality": "high",
  "provider": "xai",
  "processingTimeMs": 12500,
  "creditsCharged": 45,
  "creditsRemaining": 455
}

Error Responses

error
string
Error message describing what went wrong.
code
string
Error code for programmatic handling:
  • DAILY_LIMIT_REACHED - User hit 30/day limit
  • CONCURRENT_LIMIT_REACHED - User has 3 active generations
  • INSUFFICIENT_CREDITS - Not enough credits
  • PROVIDER_UNAVAILABLE - Both providers are down

Error Examples

{
  "code": "DAILY_LIMIT_REACHED",
  "error": "Daily limit reached (30 generations per day). Try again tomorrow.",
  "used": 30,
  "limit": 30,
  "resetAt": "2026-03-03T00:00:00.000Z"
}
{
  "error": "Insufficient credits. Required: 45, Available: 20",
  "required": 45,
  "available": 20
}
{
  "error": "You already have 3 generations in progress. Please wait for one to finish.",
  "limit": 3
}
{
  "error": "AI Provider Service is Down"
}

Implementation Details

Provider Strategy

Low Quality (quality=low):
  1. Primary: Freepik Seedream 4.5 Edit (40s budget)
  2. Fallback: xAI Grok Image (on timeout/failure)
High Quality (quality=high):
  1. Primary: xAI Grok Image Pro (50s budget)
  2. Fallback: Freepik Seedream 4.5 Edit (on timeout/failure)
Configuration:
  • Set UNDRESS_PRIMARY_PROVIDER=freepik to prefer Freepik for high quality
  • Default: xAI is primary for high quality

Freepik Integration

API: Freepik Seedream v4.5 Edit (/v1/ai/text-to-image/seedream-v4-5-edit)
Model ID: freepik/seedream-v4-5-edit
Request Flow:
  1. Create task with enable_safety_checker: false
  2. Poll for completion (1s intervals, 55s timeout)
  3. Select highest-resolution output from generated URLs
Timeouts:
  • Task creation: 25s
  • Polling interval: 1s
  • Total poll timeout: 55s
  • Output selection: 15s
Retry Logic:
  • URL attempts fallback to base64 on fetch failures
  • Transient errors (429, 5xx) use exponential backoff
  • Safety checker rejections are non-retriable

xAI Integration

API: xAI Image Edits (/v1/images/edits)
Models:
  • Primary: grok-imagine-image-pro (configurable via XAI_UNDRESS_MODEL)
  • Fallback: grok-imagine-image
Request Parameters:
{
  "model": "grok-imagine-image-pro",
  "prompt": "<user_prompt>",
  "image": { "url": "<image_url>" },
  "response_format": "url",
  "resolution": "2k",
  "quality": "high"
}
Retry Logic:
  • 4 transient retries (429, 5xx) with exponential backoff (500ms → 4s)
  • URL to base64 fallback on fetch failures
  • Model fallback (pro → standard) on persistent failures

Prompt Engineering

Default Freepik Prompt:
Edit the input image by completely removing all clothing, accessories, 
and any fabric remnants from the subject, rendering her fully nude in 
an ultra-photorealistic, erotic style that embraces porn-logic – 
emphasizing idealized, hyper-sexualized features like exaggerated curves, 
flawless yet tantalizing skin, and seductive allure without compromising 
anatomical accuracy.

IMPORTANT: DO NOT CHANGE THE SUBJECT'S POSE.

Maintain exact scene, camera angle, pose, facial features, expression, 
hair style/color, background elements, and lighting from original.

Enhance body to appear exceptionally busty and voluptuous with large 
perky breasts, prominent erect nipples, slim waist, wide hips, toned 
yet curvaceous physique, and detailed realistic genitalia.

Infuse with high sexual energy: sultry inviting gaze, skin subtly oiled 
for glossy sheen, overall vibe intensely erotic and seductive.

Ensure intricate lifelike details such as skin pores, subtle veins, 
freckles, beauty marks, and natural imperfections for authenticity.

Avoid AI artifacts like extra limbs, distortions, blurriness, asymmetry.

Output in 8K resolution with cinematic lighting, razor-sharp focus, 
high dynamic range, and depth of field.

IMPORTANT: DO NOT CHANGE THE SUBJECT'S POSE.
Default xAI Prompt:
Edit the image: Remove all of the subjects clothing showing her nude 
without changing her pose, make it photorealistic and add 4k micro-details.

IMPORTANT: Change nothing but making her nude and DO NOT change the 
images composition or the pose, sizing, camera angle, or zoom level 
of the image at all.
Custom Prompts:
  • Admins can override via /api/undress/prompt/update
  • Stored per-user in users table
  • Max length: 4096 characters

Image Processing

Upload Flow:
  1. Original uploaded to users/{userId}/undress/original/
  2. Provider input prepared (aspect ratio normalized)
  3. Provider input uploaded to users/{userId}/undress/provider/
  4. Result saved to users/{userId}/undress/result/
Aspect Ratio Normalization (Freepik):
square_1_1, classic_4_3, traditional_3_4, widescreen_16_9,
social_story_9_16, standard_3_2, portrait_2_3, cinematic_21_9
Provider Input Preparation:
  • Analyze dimensions with Sharp
  • Select nearest Freepik aspect ratio
  • Preserve metadata for xAI

Credit Management

Upfront Deduction:
const deduction = await creditService.checkAndDeductCredits(
  userId,
  featureKey, // 'ai_undress_low' or 'ai_undress_high'
  {
    description: 'AI Undress generation',
    relatedEntityType: 'undress_generation',
    relatedEntityId: generationId.toString(),
  }
);
Automatic Refund:
const refundResult = await creditService.addCredits(
  userId,
  creditsCharged,
  'refund',
  `AI Undress refund #${generationId}`,
  {
    feature: featureKey,
    generationId,
    quality,
    reason: 'Generation failed',
  }
);
Refund Triggers:
  • Generation returns error
  • Provider times out
  • No output URL returned
  • Safety checker rejection (Freepik)

Database Tracking

Table: undress_generations
CREATE TABLE undress_generations (
  id SERIAL PRIMARY KEY,
  user_id VARCHAR NOT NULL,
  status VARCHAR NOT NULL, -- 'pending', 'completed', 'failed'
  original_image_url TEXT NOT NULL,
  original_image_path TEXT NOT NULL,
  result_image_url TEXT,
  result_image_path TEXT,
  prompt TEXT NOT NULL,
  quality VARCHAR NOT NULL, -- 'low', 'high'
  requested_provider VARCHAR, -- 'xai', 'freepik'
  actual_provider VARCHAR,
  processing_time_ms INTEGER,
  error_message TEXT,
  credit_charged BOOLEAN DEFAULT false,
  refunded_at TIMESTAMP,
  refund_transaction_id INTEGER,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

Usage Notes

Consent Policy: Users MUST accept the AI Undress consent policy before accessing this endpoint. Check /api/undress/consent/status to verify consent state.
Provider Status: Check /api/undress/status before initiating generations to avoid hitting unavailable providers. The endpoint returns detailed provider availability.
Quality Selection: Use low quality for faster results and lower cost. Reserve high quality for cases where superior output quality justifies the extra 20 credits.
Automatic Cleanup: Failed generations are automatically cleaned up after 24 hours. Stuck generations can be manually cleared via /api/undress/clear-stuck.

Build docs developers (and LLMs) love