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 |
GET /entries
Section titled “GET /entries”Search, filter, sort and page through entries.
curl -H "Authorization: Bearer $PH_KEY" \ "https://api.prophouse.dev/api/v1/entries?q=rusty%20oil%20drum&type=mesh&tri_max=5000&limit=20"Search parameters
Section titled “Search parameters”| 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.
Filter parameters
Section titled “Filter parameters”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). |
Response
Section titled “Response”{ "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.
POST /entries/search/image
Section titled “POST /entries/search/image”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.
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.
GET /entries/facets
Section titled “GET /entries/facets”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.
GET /categories/rollup
Section titled “GET /categories/rollup”Active entries per category, with how many packs they come from.
{ "categories": [{ "category": "Crates", "count": 47, "pack_count": 12 }] }GET /entries/{entry_id}
Section titled “GET /entries/{entry_id}”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.
GET /entries/{entry_id}/closure
Section titled “GET /entries/{entry_id}/closure”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.
GET /entries/{entry_id}/dependents
Section titled “GET /entries/{entry_id}/dependents”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.
Thumbnails and previews
Section titled “Thumbnails and previews”| 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.
