Model Swap implementation by PiktID for processing Product Detail Page (PDP) images. This script performs automated model-swap on multiple images in a folder using the PiktID v2 API.
On-Model is an AI-powered platform by PiktID designed for fashion e-commerce. It enables brands, retailers, and marketplaces to transform their product imagery at scale:
- Model Swap — Replace models in existing product photos while preserving garments exactly as they are
- Flat-to-Model — Convert flat-lay product photography into realistic on-model images
- Identity Management — Create and maintain consistent AI model identities across your entire catalog
Try the platform at beta.on-model.com or learn more at on-model.com.
The following instructions suppose you have already installed a recent version of Python. For a general overview, please visit the API documentation. To use any PiktID API, authentication credentials are required.
Step 0 - Register at beta.on-model.com. 10 credits are given for free to all new users.
Step 1 - Clone the Model Swap repository
# Installation commands
$ git clone https://github.com/piktid/model-swap.git
$ cd model-swap
$ pip install requestsStep 2 - Prepare your PDP folder with images
Ensure your input folder contains Product Detail Page images (JPG, JPEG, or PNG format). The script automatically filters out images that don't contain models:
- Images with
_INTERNAL_in the filename are excluded - Images with
_NONMODEL_in the filename are excluded
Step 3 - Choose your identity
You can either use an existing identity code from your gallery or upload a new identity image:
Option A: Using an existing identity code
$ python model_swap.py \
--input-folder PDP/ARTICLE123 \
--username your_email@example.com \
--password your_password \
--identity-code PiktidSummer \
--output-folder results/ARTICLE123Option B: Uploading a new identity image
$ python model_swap.py \
--input-folder PDP/ARTICLE123 \
--username your_email@example.com \
--password your_password \
--identity-image identities/female/LisaSummer.jpg \
--output-folder results/ARTICLE123Step 4 - Monitor the processing
The script will automatically:
- Authenticate with the API
- Upload all PDP images from the input folder
- Create a project (or reuse an existing one)
- Upload or verify the identity
- Create a model-swap job
- Monitor job progress
- Download results to the output folder
You'll see progress updates in the console. Once complete, processed images will be saved to your output folder.
Step 5 - Review results
Results are saved to the output folder with the following structure:
output/
├── image1_v0.jpg # Processed image (version 0)
├── image2_v0.jpg # Processed image (version 0)
├── image3_v0.jpg # Processed image (version 0)
└── metadata.json # Complete job information and results
The metadata.json file contains:
- Job ID and status
- Processing results for each image
- Quality scores and processing times
- Image URLs and metadata
The script follows this sequence of API calls:
1. POST /auth/login -> Authenticate (Basic Auth -> JWT token)
2. POST /upload -> Get pre-signed S3 URL + file_id (per image)
3. PUT <upload_url> -> Upload image binary to S3
4. POST /project -> Create project (get project_id)
5. GET /identity/<code> -> Verify identity exists
or POST /identity/upload -> Upload new identity image
6. POST /model-swap -> Submit job with project_id + file_ids + identity_code
7. GET /jobs/<id>/status -> Poll until status = "completed"
8. GET /jobs/<id>/results -> Fetch output images (CloudFront URLs)
If you want to enable post-processing (skin equalization) for better results:
$ python model_swap.py \
--input-folder PDP/ARTICLE123 \
--username your_email@example.com \
--password your_password \
--identity-code PiktidSummer \
--output-folder results/ARTICLE123 \
--post-process--input-folder Path to folder containing PDP images (required)
--username API username (required)
--password API password (required)
--identity-code Existing identity code to use (optional)
--identity-image Path to identity image file to upload (optional)
--output-folder Output folder for results (default: output)
--base-url API base URL (default: https://v2.api.piktid.com)
--post-process Enable post-processing (default: False)
Note: Either --identity-code or --identity-image must be provided.
Process a PDP folder with an existing identity code:
$ python model_swap.py \
--input-folder PDP/P1KT1D-Y22 \
--username your_email@example.com \
--password your_password \
--identity-code PiktidSummer \
--output-folder output/P1KT1D-Y22Upload a new identity and process images:
$ python model_swap.py \
--input-folder PDP/P1KT1D-Y22 \
--username your_email@example.com \
--password your_password \
--identity-image identities/female/LisaSummer.jpg \
--output-folder output/P1KT1D-Y22Enable post-processing (skin equalization):
$ python model_swap.py \
--input-folder PDP/P1KT1D-Y22 \
--username your_email@example.com \
--password your_password \
--identity-code PiktidSummer \
--output-folder output/P1KT1D-Y22 \
--post-processFor processing multiple PDP folders at once, use batch_swap.py. It runs multiple ModelSwap instances in parallel using a thread pool, with each worker handling a complete independent workflow.
$ python batch_swap.py \
--input-dir PDP/ \
--username your_email@example.com \
--password your_password \
--identity-code PiktidSummer \
--output-dir results/This scans PDP/ for subfolders and processes each one as a separate job. Results are saved to results/<folder-name>/.
$ python batch_swap.py \
--input-folders PDP/ARTICLE1 PDP/ARTICLE2 PDP/ARTICLE3 \
--username your_email@example.com \
--password your_password \
--identity-image identities/female/LisaSummer.jpg \
--output-dir results/ \
--parallel 5--input-dir Directory containing PDP subfolders (mutually exclusive with --input-folders)
--input-folders Specific PDP folder paths to process (mutually exclusive with --input-dir)
--username API username (required)
--password API password (required)
--identity-code Existing identity code to use (optional)
--identity-image Path to identity image file to upload (optional)
--output-dir Base output directory (default: output)
--base-url API base URL (default: https://v2.api.piktid.com)
--post-process Enable post-processing (default: False)
--parallel Number of parallel workers (default: 3, max: 5)
Parallelism is capped at 5 to respect the API rate limit (5 requests/minute on /model-swap). The built-in retry mechanism handles any 429 responses that occur when jobs are submitted close together.
A JSON summary file is saved to the output directory after each batch run with timing and success/failure details for every folder.
The script includes built-in handling for API rate limits and token expiry:
- Rate limiting (429): All API calls automatically retry with exponential backoff (1s, 2s, 4s, 8s, 16s) plus random jitter, up to 5 retries per request
- Token expiry (401): If a token expires during a long-running workflow, the script re-authenticates automatically and retries the failed request
The /model-swap endpoint is rate-limited to 5 requests per minute. The retry mechanism handles this transparently.
Authentication failed: 401
Solution: Check your username and password. Verify the API server is running and accessible.
No processable images found in PDP/ARTICLE123
Solution:
- Verify the input folder path is correct
- Check that the folder contains image files (JPG, JPEG, PNG)
- Note: Images with
_INTERNAL_or_NONMODEL_in filenames are automatically excluded
Error checking identity: ...
Solution:
- Verify the identity code exists in your gallery at beta.on-model.com
- Or provide an
--identity-imagepath to upload a new identity
Rate limited (429). Waiting 2.1s before retry 1/5...
This is normal behavior. The script automatically retries with increasing delays. If you see "Max retries exceeded", wait a minute and try again.
Timeout: Job took longer than 1200 seconds
Solution: The job may be taking longer than expected. Check the API server status. You can modify the max_wait_time parameter in the wait_for_job method if needed.
Authentication error: Connection refused
Solution:
- Verify the API server is running
- Check the
--base-urlis correct - Ensure network connectivity to the API server
The script will exit with an error code if:
- Authentication fails
- No images are found in the input folder
- Identity upload/verification fails
- Job creation fails
- Job does not complete successfully
- Results download fails
- Rate limit retries are exhausted
Check the console output for detailed error messages.
- On-Model Website — Learn about the platform
- On-Model App — Try the app (beta)
- API Documentation — Full API reference
- PiktID — Company website
- Discord — Community and support