Endpoints
GET /api/v1/data/benchmarks
The benchmarks your key can query, each with its id, product, title, and the dimension parameters it exposes. Use a benchmark id as the benchmark parameter on the other endpoints.
1benchmarks = client.list_benchmarks().data
GET /api/v1/data/catalog?benchmark=<id>
The filter dimensions a benchmark exposes, each with its allowed values (labeled where the raw value is opaque, e.g. conditions and layers), plus the total item count for your tier. The filters block maps each /api/v1/data/items query parameter to the values allowed for your key, so you can build a valid query without having to memorize the allowed identifiers. Omit benchmark only if your key sees a single benchmark.
1catalog = client.get_catalog(benchmark="synthetic-face-v1")
GET /api/v1/data/items
A filtered list of items for a benchmark (ids and attributes, no storage paths). The filterable dimensions are defined by the benchmark, so you select images with exactly the discrimination it supports, and the parameter set differs per benchmark (for example scene exists only on synthetic-face-v1). Pick a benchmark tab below to see its parameters and values; call /api/v1/data/catalog?benchmark=<id> for the live source of truth. Every parameter is optional; omit a parameter to include all values for that dimension, and each accepts a comma-separated list matching any of the given values (OR within the dimension), e.g. skin_tone=dark,brown or perturbation=jpeg_q70,jpeg_q80. Unknown values for a fixed dimension return 400 with the allowed set.
Parameters for synthetic-face-v1 (tiers: test, live). The filter dimensions and their values differ per benchmark; /catalog is the live source of truth.
| Parameter | Meaning | Allowed values |
|---|---|---|
skin_tone | Skin-tone band on a 6-level light-to-dark scale | very_light, light, intermediate, tan, brown, dark |
gender | Perceived gender of the face | female, male |
kind | Real (a genuine, unmodified photo) or fake (AI-generated) | real, fake |
generator | Model that produced the image (fake only; null for real) | see /catalog generators |
perturbation | Image condition applied after generation. Alias: condition. jpeg_q* = JPEG at that quality; blur_*/noise_*/resize_* = that transform; *_pipeline = a re-encode through that platform's upload pipeline (fb=Facebook, ig=Instagram, tt=TikTok, x=X) | clean, jpeg_q30/50/70/80/95, blur_1/2/4, noise_5/10, resize_0.5/0.75, fb_pipeline, ig_pipeline, tt_pipeline, x_pipeline |
layer | Coarse grouping of conditions: clean = no perturbation; layer1 = one lossy transform; layer2 = a platform pipeline; layer2_recropped = a platform pipeline then re-detected and re-cropped | clean, layer1, layer2, layer2_recropped |
scene | Shot context. Synthetic-face only | indoor, outdoor, selfie |
ttp_tactic | Adversarial tactic (the attacker's goal) behind the item; null for real | impersonation |
ttp_technique | Technique that realizes the tactic; null for real | identity_conditioned_synthesis |
| Parameter | Meaning | Allowed values |
|---|---|---|
benchmark | Which benchmark to query (see /api/v1/data/benchmarks). Accepts the versioned id or its stable code. Omit only if your key sees one benchmark | synthetic-face-v1 or MG-SYN-01 |
base_id | Pull every variant of ONE base image. Hold an item's base_id and add perturbation= to fetch another condition of the same image | any item's base_id |
source_real_id | Pull the full lineage descended from one sourced real image (the real, its fakes, and their variants) | any item's source_real_id |
limit | Page size (values above 500 are clamped; response sets limit_clamped:true) | 1-500 (default 100) |
offset | Pagination offset (order: created_at ascending) | >=0 |
cursor | Stable keyset pagination over a growing table (use instead of offset). Pass the response next_cursor for the next page | opaque string from next_cursor |
lineage | Page over whole lineages: every row of each matched lineage is returned (limit/offset count lineages, not rows) | true |
exclude_owned | Offset mode only. Omit items you already own. Response adds remaining/owned/total_matching and subset_exhausted | true |
distinct_identities | Return one representative item per person (dedupe by identity_id; opt-in, no default cap). Composes with filters. Response sets mode=distinct_identities | true |
Parameters for passport-pad-v1 (tiers: live). The filter dimensions and their values differ per benchmark; /catalog is the live source of truth.
| Parameter | Meaning | Allowed values |
|---|---|---|
skin_tone | Skin-tone band on a 6-level light-to-dark scale | very_light, light, intermediate, tan, brown, dark |
gender | Perceived gender of the face | female, male |
kind | Real (a licensed reference face) or fake (an identity-preserving synthetic attack of that person) | real, fake |
generator | Editor that produced the attack (fake only; null for real) | hidream_o1, qwen_image_edit |
perturbation | Image condition. Alias: condition. This benchmark is a pristine cohort today, so only clean is present; capture and document emulation are planned | clean |
layer | Coarse grouping of conditions. Pristine cohort, so clean only today | clean |
ttp_tactic | Adversarial tactic (the attacker's goal) behind the item; null for real | impersonation |
ttp_technique | Technique that realizes the tactic; null for real | identity_preserving_edit |
| Parameter | Meaning | Allowed values |
|---|---|---|
benchmark | Which benchmark to query (see /api/v1/data/benchmarks). Accepts the versioned id or its stable code. Omit only if your key sees one benchmark | passport-pad-v1 or MG-KYC-01 |
base_id | Pull every variant of ONE base image. Hold an item's base_id and add perturbation= to fetch another condition of the same image | any item's base_id |
source_real_id | Pull the full lineage descended from one sourced real image (the real, its fakes, and their variants) | any item's source_real_id |
limit | Page size (values above 500 are clamped; response sets limit_clamped:true) | 1-500 (default 100) |
offset | Pagination offset (order: created_at ascending) | >=0 |
cursor | Stable keyset pagination over a growing table (use instead of offset). Pass the response next_cursor for the next page | opaque string from next_cursor |
lineage | Page over whole lineages: every row of each matched lineage is returned (limit/offset count lineages, not rows) | true |
exclude_owned | Offset mode only. Omit items you already own. Response adds remaining/owned/total_matching and subset_exhausted | true |
distinct_identities | Return one representative item per person (dedupe by identity_id; opt-in, no default cap). Composes with filters. Response sets mode=distinct_identities | true |
exclude_owned=true, once you own every item matching a filter, /items returns a normal 200 with data: [], remaining: 0, and subset_exhausted: true plus a message. Check remaining (or subset_exhausted), not a status code: it means there is nothing new to pull for that selection. Broaden the filter (another cell, generator, or perturbation) to get more. Likewise, downloading an item you already own is not an error, it returns the URL for free with charged: false, already_owned: true.1# fake, dark or brown cell, JPEG q70 or q80, first 22page = client.list_items(3benchmark="synthetic-face-v1",4kind="fake",5skin_tone="dark,brown", # raw client: comma string (iter_items also takes a list)6perturbation="jpeg_q70,jpeg_q80",7limit=2,8).result9for item in page.data:10print(item.id, item.skin_tone, item.perturbation)
source_real_id: it returns the sourced real image plus every fake and perturbed variant derived from it, all sharing that id.GET /api/v1/data/download/:itemId
Returns a short-lived signed URL for one item. For live keys this debits one credit before the URL is returned. Sending an Idempotency-Key header is optional but recommended: it de-duplicates retries so a repeated request returns the original result without a second charge. Omit it and a retried download is not de-duplicated, so it could be charged again. Fetch the returned url directly (no auth header on that request).
1import urllib.request2dl = client.download_item(item_id=item.id) # item from the /items call above; Idempotency-Key set for you3# dl.url is a short-lived signed URL; fetch it with no auth header4urllib.request.urlretrieve(dl.url, "image.jpg")
GET /api/v1/data/usage
Your current credit balance and tier. It is worth checking your balance before a large pull, so a run does not stop partway with a 402.
1usage = client.get_usage() # usage.tier, usage.balance