How to Export Image Metadata from PhotoShelter for Photographers
PhotoShelter for Photographers is a cloud-based photo hosting, proofing, and portfolio platform. Here's how to extract your image metadata into a spreadsheet for quality assessment.
PhotoShelter for Photographers does not have a built-in metadata export to CSV. PhotoShelter preserves and indexes IPTC and EXIF metadata from your uploads, but the only way to extract that metadata as a spreadsheet (without downloading every image file) is through the PhotoShelter REST API. The API provides full access to IPTC fields, EXIF data, and file properties across your entire library or for specific galleries.
PhotoShelter API v4 — Full Library Export
The PhotoShelter REST API (v4) provides read access to all images in your account, including IPTC metadata (title, caption, keywords, copyright, creator), EXIF data (camera, lens, exposure settings), and file properties. No image files are downloaded; only metadata is retrieved.
import requests
import csv
import time
API_KEY = "your_api_key"
BASE = "https://www.photoshelter.com/psapi/v4"
session = requests.Session()
session.headers.update({
"X-PS-Api-Key": API_KEY,
"Accept": "application/json",
})
# Authenticate
auth = session.post(f"{BASE}/mem/authenticate", json={
"email": "your_email@example.com",
"password": "your_password",
})
token = auth.json()["data"]["attributes"]["token"]
session.headers.update({"X-PS-Auth-Token": token})
def list_all_images():
"""List all images with IPTC/EXIF metadata."""
all_images = []
page = 1
per_page = 100
while True:
resp = session.get(f"{BASE}/mem/images", params={
"page": page,
"per_page": per_page,
})
data = resp.json()
images = data.get("data", [])
if not images:
break
all_images.extend(images)
page += 1
if len(images) < per_page:
break
time.sleep(0.5) # respect rate limits
return all_images
images = list_all_images()
with open("photoshelter_metadata.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow([
"Image ID", "Filename", "Title", "Caption",
"Keywords", "Copyright", "Creator",
"City", "State", "Country",
"File Type", "File Size", "Width", "Height",
"Camera Make", "Camera Model", "Lens",
"Date Created", "Date Uploaded",
])
for img in images:
attrs = img.get("attributes", {})
iptc = attrs.get("iptc", {})
exif = attrs.get("exif", {})
writer.writerow([
img.get("id", ""),
attrs.get("file_name", ""),
iptc.get("title", ""),
iptc.get("caption", ""),
"; ".join(iptc.get("keywords", [])),
iptc.get("copyright", ""),
iptc.get("creator", ""),
iptc.get("city", ""),
iptc.get("state", ""),
iptc.get("country", ""),
attrs.get("file_type", ""),
attrs.get("file_size", ""),
attrs.get("width", ""),
attrs.get("height", ""),
exif.get("make", ""),
exif.get("model", ""),
exif.get("lens", ""),
iptc.get("date_created", ""),
attrs.get("uploaded_at", ""),
])
print(f"Exported {len(images)} images to photoshelter_metadata.csv")Gallery-Scoped API Export
If you want to export metadata for a specific gallery or collection rather than your entire library, you can scope the API request to a single gallery. This is useful for checking metadata quality on a per-shoot or per-client basis before delivery.
import requests
import csv
API_KEY = "your_api_key"
BASE = "https://www.photoshelter.com/psapi/v4"
session = requests.Session()
session.headers.update({
"X-PS-Api-Key": API_KEY,
"Accept": "application/json",
})
# Authenticate (same as Method 1)
auth = session.post(f"{BASE}/mem/authenticate", json={
"email": "your_email@example.com",
"password": "your_password",
})
token = auth.json()["data"]["attributes"]["token"]
session.headers.update({"X-PS-Auth-Token": token})
# Step 1: List galleries to find the one you want
galleries = session.get(f"{BASE}/mem/galleries", params={
"per_page": 50,
}).json()
print("Your galleries:")
for g in galleries.get("data", []):
attrs = g.get("attributes", {})
print(f" {g['id']} {attrs.get('name', 'Untitled')}")
# Step 2: Export metadata from a specific gallery
GALLERY_ID = "your_gallery_id" # paste from list above
def list_gallery_images(gallery_id):
"""List all images in a gallery with metadata."""
all_images = []
page = 1
per_page = 100
while True:
resp = session.get(
f"{BASE}/mem/galleries/{gallery_id}/images",
params={"page": page, "per_page": per_page},
)
data = resp.json()
images = data.get("data", [])
if not images:
break
all_images.extend(images)
page += 1
if len(images) < per_page:
break
return all_images
images = list_gallery_images(GALLERY_ID)
with open("gallery_metadata.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow([
"Image ID", "Filename", "Title", "Caption",
"Keywords", "Copyright", "Creator",
"File Type", "File Size", "Width", "Height",
"Date Created", "Date Uploaded",
])
for img in images:
attrs = img.get("attributes", {})
iptc = attrs.get("iptc", {})
writer.writerow([
img.get("id", ""),
attrs.get("file_name", ""),
iptc.get("title", ""),
iptc.get("caption", ""),
"; ".join(iptc.get("keywords", [])),
iptc.get("copyright", ""),
iptc.get("creator", ""),
attrs.get("file_type", ""),
attrs.get("file_size", ""),
attrs.get("width", ""),
attrs.get("height", ""),
iptc.get("date_created", ""),
attrs.get("uploaded_at", ""),
])
print(f"Exported {len(images)} images to gallery_metadata.csv")What metadata fields can you export?
| Field | Full Library Export | Gallery Export |
|---|---|---|
| Image ID | ✓ | ✓ |
| Filename | ✓ | ✓ |
| Title (IPTC) | ✓ | ✓ |
| Caption (IPTC) | ✓ | ✓ |
| Keywords (IPTC) | ✓ | ✓ |
| Copyright (IPTC) | ✓ | ✓ |
| Creator (IPTC) | ✓ | ✓ |
| Location: City, State, Country | ✓ | ✓ |
| File type | ✓ | ✓ |
| File size | ✓ | ✓ |
| Dimensions (W x H) | ✓ | ✓ |
| EXIF: Camera make / model | ✓ | ✓ |
| EXIF: Lens | ✓ | ✓ |
| EXIF: Exposure settings | ✓ | ✓ |
| Date created (IPTC) | ✓ | ✓ |
| Date uploaded | ✓ | ✓ |
| Gallery membership | All galleries | Current gallery |
| Collection info | ✓ | ✕ |
- No built-in CSV export. PhotoShelter for Photographers does not offer a click-to-download metadata CSV anywhere in the UI. The API is the only way to get metadata without downloading the actual image files.
- Images only. PhotoShelter for Photographers does not support video files. If you need to assess metadata on video assets, you will need a different platform or tool.
- EXIF data is read-only. PhotoShelter displays EXIF metadata (camera, lens, exposure, GPS) but does not allow editing it within the platform. Only IPTC fields (title, caption, keywords, copyright) are editable through the PhotoShelter UI.
- Batch edits within PhotoShelter are append-based. When batch editing IPTC metadata in the PhotoShelter UI, you can append, replace, or delete values. However, the metadata in your export reflects the current state, regardless of how it was edited.
- API rate limits apply. For large libraries (10,000+ images), add delays between API requests as shown in the script. Check the PhotoShelter Developer Portal for current rate limit policies.
- IPTC not re-embedded in all formats. When files are downloaded from PhotoShelter, IPTC metadata is re-embedded into JPEG and TIFF files. PSD files and some proprietary RAW formats do not receive re-embedded IPTC data.
You have your metadata export.
Now score it.
Upload your CSV or Excel file to MQS and get a structural metadata health score out of 100 with dimension breakdowns and actionable diagnostics.