Model swap
Replace model identities in multiple PDPs at once
You will need an API token to send HTTP requests. See Authentication for instructions.
Quick start
Create a project to organize your images. The project_id will be used in subsequent requests. See Creating a project for details.
Upload one or more PDP images to the project. This is a two-step process:
- Request a pre-signed upload URL
- PUT the image binary to that URL
Collect all file_id values for the next step. See Uploading images for details.
Start a model swap job by providing the identity to swap onto the images and the list of uploaded file IDs. See Starting a job for details.
Poll for notifications to track job progress. Use the id_task parameter with your job ID. See Polling notifications for details.
Uploading identities
Before starting a swap job, you need an identity_code. You can either use an existing identity from your gallery or upload a new one.
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
identity_image_path = "path/to/identity.jpg"
with open(identity_image_path, "rb") as f:
response = requests.post(
api_url + "/identity/upload",
headers={"Authorization": "Bearer " + access_token},
files={"image": f},
data={"name": "Model A"}, # Optional custom name
).json()
identity_code = response["identity_code"]
print(f"Identity uploaded: {identity_code}"){
"identity_code": "id_xyz...", // IDENTITY_CODE
"name": "Model A",
"face_detected": true,
"success": true,
// ...
}You can list existing identities using:
Creating a project
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
response = requests.post(
api_url + "/project",
headers={"Authorization": "Bearer " + access_token},
json={"project_name": "my-campaign"},
).json()
project_id = response["project_id"]
project_name = response["project_name"]{
"project_id": "abc123...", // PROJECT_ID
"project_name": "my-campaign"
}Uploading images
You can repeat this process for each image you want to process. All file_id values must be collected to start a job.
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
project_name = "my-campaign"
image_path = "path/to/image.jpg"
# Step 1: Get pre-signed upload URL
response = requests.post(
api_url + "/upload",
headers={"Authorization": "Bearer " + access_token},
json={
"project_name": project_name,
"filename": "model-photo-1.jpg",
},
).json()
upload_url = response["upload_url"]
content_type = response["content_type"]
file_id = response["file_id"]
# Step 2: Upload the image binary
with open(image_path, "rb") as f:
requests.put(
upload_url,
headers={"Content-Type": content_type},
data=f.read(),
)
print(f"Uploaded file ID: {file_id}"){
"upload_url": "https://s3...", // Pre-signed PUT URL
"download_url": "https://...",
"project_id": "abc123...",
"project_name": "my-campaign",
"file_id": "img_001...", // FILE_ID
"filename": "model-photo-1.jpg",
"content_type": "image/jpeg"
}The upload_url is only valid for a limited time. Upload the image immediately after receiving the response.
Starting a job
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
project_id = "abc123..."
identity_code = "id_xyz..." # From identity upload or gallery
file_ids = ["img_001...", "img_002...", "img_003..."]
response = requests.post(
api_url + "/model-swap",
headers={"Authorization": "Bearer " + access_token},
json={
"identity_code": identity_code,
"project_id": project_id,
"images": file_ids,
"post_process": False, # Optional: enable post-processing
},
).json()
job_id = response["job_id"]
print(f"Job started: {job_id}"){
"job_id": "job_abc123...", // JOB_ID
"status": "pending",
"message": "Job created successfully"
}Post-processing
Set post_process to true (default) in the job request to enable automatic post-processing of results. The job status will include post_processing_status to track this additional step.
{
"identity_code": "id_xyz...",
"project_id": "abc123...",
"images": ["img_001...", "img_002..."],
"post_process": true
}Polling notifications
Poll for notifications to track job progress. Use the id_task parameter with your job ID.
import time
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
job_id = "job_abc123..."
# Poll for notifications (recommended: every 3-5 seconds)
for _ in range(120): # 10 minute timeout
response = requests.post(
api_url + "/notifications",
headers={"Authorization": "Bearer " + access_token},
json={
"id_task": job_id,
"name_list": ["completed", "error"],
},
).json()
for notification in response:
print(f"Notification: {notification['name']}")
print(f"Data: {notification['data']}")
if notification["name"] == "completed":
print("Job completed!")
break
elif notification["name"] == "error":
print(f"Error: {notification['data']}")
break
else:
time.sleep(5)
continue
break[
{
"id": 12345,
"name": "completed", // Notification type
"timestamp": 1702819200.0,
"data": { // Job-specific data
"job_id": "job_abc123...",
"status": "completed"
}
}
]Retrieving results
Once the job is complete, retrieve the processed images.
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
job_id = "job_abc123..."
response = requests.get(
api_url + f"/jobs/{job_id}/results",
headers={"Authorization": "Bearer " + access_token},
).json()
for result in response["results"]:
print(f"Image {result['image_index']}: {result['url']}"){
"job_id": "job_abc123...",
"job_type": "model_swap",
"status": "completed",
"results": [
{
"image_index": 0,
"url": "https://...", // Result image URL
"status": "completed"
},
{
"image_index": 1,
"url": "https://...",
"status": "completed"
}
],
"summary": {
// Job statistics
}
}Bulk download
For bulk downloads, generate a temporary download URL that packages all results into a ZIP file.
import requests
api_url = "https://v2.api.piktid.com"
access_token = "your_access_token"
job_id = "job_abc123..."
# Generate download URL
response = requests.post(
api_url + "/download",
headers={"Authorization": "Bearer " + access_token},
json={"job_id": job_id},
).json()
download_url = response["download_url"]
expires = response["expires"]
print(f"Download URL: {download_url}")
print(f"Expires: {expires}")
# Download the ZIP file (no auth required for the token URL)
zip_response = requests.get(download_url)
with open("results.zip", "wb") as f:
f.write(zip_response.content){
"download_url": "https://v2.api.piktid.com/download/token123...",
"expires": "2024-12-17T11:00:00Z" // URL expiration time
}