Skip to content

Entries and search

An entry is one prop as it appears in the library: a name, a category, tags, and a current version (its face object). These endpoints search and read entries. All of them need only read scope.

Method and path Purpose
GET /entries Browse, keyword and natural-language search, similar props
POST /entries/search/image Search by example image
GET /entries/facets Filter values with counts
GET /categories/rollup Categories with entry and pack counts
GET /entries/{entry_id} Entry detail
GET /entries/{entry_id}/closure Everything a pull of this entry brings along
GET /entries/{entry_id}/dependents Everything that uses this entry
GET /entries/{entry_id}/thumbnail Thumbnail image
GET /entries/{entry_id}/preview 3D, image or audio preview
GET /previews/artifacts/{artifact_id} One specific preview or thumbnail file

Search, filter, sort and page through entries.

Terminal window
curl -H "Authorization: Bearer $PH_KEY" \
"https://api.prophouse.dev/api/v1/entries?q=rusty%20oil%20drum&type=mesh&tri_max=5000&limit=20"
Parameter Type Description
q string Search text. Ranked by a blend of keyword matches (name, pack, category, tags, comments) and visual meaning, so descriptions like weathered wooden crate work. Bare words match as prefixes; "quoted phrases" match exactly.
similar_to integer An entry id. Ranks entries by how much they look like that entry. The entry’s own versions are excluded.
sort string relevance, name, date_indexed, date_updated, blob_size or tri_count. Defaults to relevance when q or similar_to is set, otherwise name.
order string asc (default) or desc. Ignored for relevance, which is always best first.
limit integer 1 to 200, default 50.
cursor string Opaque cursor from the previous page.

sort=relevance requires q or similar_to (422 otherwise). similar_to only works with relevance (422 if you pass another sort). Ranked results carry a score field and are capped at the best 1,000 matches.

Filters combine with AND. Parameters marked repeatable accept several values (?type=mesh&type=skeletal_mesh), which combine with OR.

Parameter Type Description
pack integer, repeatable Pack id.
category string, repeatable Category name.
uncategorized boolean Include entries with no category (ORs with category).
exclude_category string, repeatable Drop entries in these categories.
exclude_uncategorized boolean Also drop entries with no category.
tag string, repeatable Tag name.
type string, repeatable Entry type, for example mesh, skeletal_mesh, texture, material, blueprint, vfx, audio, animation, sequence. Open set.
variant boolean Only entries that are (or are not) marked as variants.
variant_group integer Only members of this variant group.
preview string none, ready or unavailable.
review string draft, in_review, changes_requested or approved.
has_collision boolean Mesh has collision.
nanite boolean Nanite enabled.
tri_min, tri_max integer Triangle count range.
vert_min, vert_max integer Vertex count range.
material_min, material_max integer Material count range.
lod_min, lod_max integer LOD count range.
bounds_min, bounds_max number Bounding-box size range.
include_deprecated boolean Include deprecated entries (excluded by default).
{
"entries": [
{
"id": 412,
"name": "SM_Barrel_Rusty",
"entry_type": "mesh",
"lineage_id": "guid:6F9619FF8B86D011B42D00C04FC964FF",
"object_id": 1880,
"is_variant": false,
"variant_label": null,
"variant_group": { "id": 12, "label": "SM_Barrel", "count": 3 },
"category": "Barrels",
"category_locked": false,
"has_thumbnail": true,
"preview_status": "ready",
"preview_kind": "glb",
"review_status": "approved",
"status": "active",
"asset_class": "StaticMesh",
"origin_path": "/Game/Props/Industrial/SM_Barrel_Rusty",
"source_ext": null,
"content_hash": "9f2c...e41a",
"blob_size": 1048576,
"engine_version": "5.8.0",
"pack": { "id": 3, "name": "Industrial Yard" },
"metadata": {
"tri_count": 1840, "vert_count": 1022, "material_count": 2, "lod_count": 3,
"has_collision": true, "nanite_enabled": false,
"bounds": { "x": 62.5, "y": 62.5, "z": 91.0 }
},
"date_indexed": "2026-07-12T18:04:05Z",
"date_updated": "2026-07-20T09:11:40Z",
"score": 0.032787
}
],
"next_cursor": null
}
Field Description
object_id, content_hash, blob_size, engine_version, asset_class, origin_path The entry’s current version (face object).
lineage_id The version history this entry belongs to. See Versions.
variant_group {id, label, count} when the entry is grouped with sibling variants; count is the whole group’s size. null otherwise.
preview_status none (not generated yet), ready or unavailable.
preview_kind glb, image, audio or null.
review_status Review state of the current version. draft when never reviewed.
status active or deprecated.
source_ext Original file extension for non-Unreal source files (fbx, wav), null for Unreal packages.
metadata Also includes texture_count, max_texture_res, pbr_channels, blend_mode, two_sided, source_app, source_authored_at, audio_duration, sample_rate, channel_count, texture_width, texture_height, texture_format, bone_count, anim_length, emitter_count. Any can be null.
score Present only on ranked (relevance) results.

Errors: 422 VALIDATION for bad parameter combinations or a mismatched cursor; 404 ENTRY_NOT_FOUND for an unknown similar_to; 409 EMBEDDINGS_UNAVAILABLE when the similar_to entry has no image embedding yet (for example, no thumbnail); 503 EMBEDDINGS_UNAVAILABLE if visual search is temporarily unavailable. Text search keeps working on keywords alone when visual ranking is unavailable.

Search with an example image: concept art, a screenshot, a photo. Send the raw PNG or JPEG bytes (up to 16 MiB) as the body. Every GET /entries filter works as a query parameter, and q acts as an extra keyword filter. This is a read: read scope is enough.

Terminal window
curl -X POST -H "Authorization: Bearer $PH_KEY" \
-H "Content-Type: image/png" --data-binary @concept.png \
"https://api.prophouse.dev/api/v1/entries/search/image?type=mesh&limit=20"
{ "entries": [ { "id": 88, "name": "SM_Lamp_Street", "score": 0.912345 } ], "total_ranked": 640 }

Returns one page only (no cursor); raise limit (up to 200) for more. total_ranked is how many entries were ranked. Errors: 422 if the body is not a PNG or JPEG or is over 16 MiB; 503 EMBEDDINGS_UNAVAILABLE if visual search is temporarily unavailable.

Takes the same filter parameters as GET /entries and returns the values available for each filter, with counts. Each dimension ignores its own filter so alternatives stay visible (filtering to type=mesh still lists the other types).

{
"packs": [{ "id": 3, "name": "Industrial Yard", "count": 214 }],
"categories": [{ "value": "Barrels", "count": 18 }],
"tags": [{ "id": 5, "name": "hero", "color": "#e5484d", "count": 9 }],
"types": [{ "value": "mesh", "count": 1320 }],
"variant": [{ "value": false, "count": 1400 }, { "value": true, "count": 96 }],
"preview": [{ "value": "ready", "count": 1210 }],
"review": [{ "value": "draft", "count": 1300 }, { "value": "approved", "count": 150 }],
"metadata": {
"tri_count": { "min": 12, "max": 482000 },
"vert_count": { "min": 8, "max": 260000 },
"material_count": { "min": 1, "max": 14 },
"lod_count": { "min": 1, "max": 6 },
"bounds": { "min": 2.0, "max": 5120.0 }
}
}

A category value of null is the uncategorized bucket.

Active entries per category, with how many packs they come from.

{ "categories": [{ "category": "Crates", "count": 47, "pack_count": 12 }] }

Everything in the summary above, plus:

Field Description
ever_pulled true once the entry has been downloaded or pulled into a project. Pulled entries cannot be hard-deleted.
face {object_id, content_hash, package_guid, lineage_anchor, date_ingested, published_by} for the current version. published_by is {id, name} or null.
tags [{id, name, color}]
comments Every comment on the entry, oldest first, in the comment shape.
collections [{id, name}]
review The current version’s review record, or null for draft. See Reviews.
metadata_doc The version’s structured metadata document (see Push), or null.
preview_artifact_id, thumbnail_artifact_id Ids of the exact preview and thumbnail files now in use, for annotations. null when none.

Deprecated entries stay readable here. Unknown id: 404 ENTRY_NOT_FOUND.

What a pull of this entry would bring: the current version plus every hard and soft dependency.

{
"entry_id": 412,
"root_object_id": 1880,
"total_objects": 6,
"total_bytes": 4718592,
"members": [
{
"object_id": 1880, "content_hash": "9f2c...e41a", "lineage_id": "guid:6F96...64FF",
"asset_class": "StaticMesh", "asset_name": "SM_Barrel_Rusty",
"origin_path": "/Game/Props/Industrial/SM_Barrel_Rusty",
"blob_size": 1048576, "engine_version": "5.8.0",
"depth": 0, "edge": "root", "via_object_id": null, "shared_with_count": 0,
"entry_id": 412, "has_thumbnail": true
}
]
}

edge is root, hard or soft. via_object_id is the member one step closer to the root (null for the root). shared_with_count is how many other entries’ closures also contain that member. entry_id is set when the member is some entry’s current version.

The reverse: everything that uses this entry’s current version (for a texture, the materials and meshes built on it).

{
"entry_id": 77,
"root_object_id": 950,
"total_objects": 4,
"used_by_entries": 2,
"members": [
{
"object_id": 1880, "content_hash": "9f2c...e41a", "lineage_id": "guid:6F96...64FF",
"asset_class": "StaticMesh", "asset_name": "SM_Barrel_Rusty", "origin_path": "/Game/Props/Industrial/SM_Barrel_Rusty",
"blob_size": 1048576, "engine_version": "5.8.0",
"depth": 2, "edge": "hard", "via_object_id": 951,
"entry_id": 412, "entry_name": "SM_Barrel_Rusty", "entry_status": "active", "has_thumbnail": true
}
]
}

depth 1 is a direct dependent. via_object_id points one step back toward this entry. Members that are another entry’s current version carry entry_id and entry_name; used_by_entries counts those.

Endpoint Response
GET /entries/{entry_id}/thumbnail 302 to the PNG (at most 512 x 512). 404 NOT_FOUND when the entry has no thumbnail.
GET /entries/{entry_id}/preview 302 to the preview: model/gltf-binary (GLB) for meshes, image/png for textures, audio/wav for audio. 404 NOT_FOUND when there is none.
GET /previews/artifacts/{artifact_id} 302 to one specific thumbnail or preview file, even after it has been replaced. Use it with preview_artifact_id and annotations. 404 for unknown ids.

Follow the redirect without your Authorization header (see presigned URLs). Use has_thumbnail, preview_status and preview_kind from the entry to decide whether to request these at all.