Documentation

Search API

peryx maintains a derived search index for entities observed by active ecosystem owners. Search reads metadata and never reads artifact bytes. The authoritative metadata store can rebuild the index after a schema change or restore.

Record schema

Each implementation maps its entities to this record:

FieldMeaning
display_labelName shown to the caller
resource_keyStable name used for matching and ordering
routeRepository route
indexIndex name
ecosystemRegistered ecosystem identifier
type_labelImplementation term for the entity
typeuploaded, cached, or override
availableWhether this instance can serve at least one artifact
summaryOptional implementation-provided summary

The type_label field lets a mixed result page use the implementation's terminology. Clients should identify the implementation through ecosystem, not by matching type_label text.

Endpoints

  • GET /+search searches readable records across configured indexes.
  • GET /{route}/+search searches one route and ignores a conflicting route query value.

Both endpoints return one response schema and accept the same query fields.

Query fields

FieldValuesDefaultContract
qText of 2+ characters, or re:<expression> for an operatorEmptyMatches the ecosystem's search document
routeConfigured routeAnyRestricts a global query
typeall, uploaded, cached, overrideallRestricts record source
availabilityall, localallRestricts records by local byte availability
pagePositive integer1Selects a result page
page_size25, 50, or 10025Sets the result count

Plain text uses case-insensitive substring matching and needs at least two characters: a shorter query names no indexed n-gram, so answering it would mean reading every indexed document. The re: prefix selects a case-insensitive regular expression, which has no n-gram to seek on and therefore does read every indexed document; it is restricted to a caller the request authenticates as an operator, and anyone else receives 403 Forbidden. Both modes inspect an ecosystem-provided search document, so a match does not need to appear in display_label or resource_key. A one-character query, an invalid expression, or an unknown availability value returns 400 Bad Request.

The ecosystem implementations build searchable text from these fields:

EcosystemCategoryFields
PyPIIdentityNormalized, project-detail, and core-metadata names
PyPICatalogVersions, distribution filenames, and per-file Requires-Python
PyPICore metadataRequires-Python, summary, description, author and maintainer names and email addresses, license fields and files, keywords, dependencies and extras, classifiers, import names and namespaces, project URL labels and values, home page, and description content type
OCIRepositoryRepository name and every tag

For example, a PyPI project named acme with the summary Temporary upload matches q=temporary. An OCI repository named team/app with the tag release-candidate matches q=candidate.

peryx indexes at most 64 KiB of each search document, and both matching modes read that same window. A query and a longer query containing it therefore return the same records; neither matches text past the limit.

Response schema

The response echoes query, route, type, availability, page, and page_size. It adds total and a results array of the records above. total counts all readable matches after policy and availability filters. Results sort by display_label, route, then resource_key. Search does not rank by relevance.

Access control

The query includes the caller's read grants before counting and paging. An unreadable name contributes no row and does not change total. Policy-hidden, trashed, and revoked artifacts do not make a record visible.

Availability

An implementation computes available from the artifact placement projection. A record is local when at least one eligible artifact has verified bytes on this instance. Catalog-only metadata without local bytes remains searchable unless the caller selects availability=local.

Rebuilds

Startup discards an incompatible derived index and rebuilds it from metadata. Repository mutations mark affected search records stale. The next query refreshes them before returning a page. Each implementation documents its manual reindex command with its client workflows.

Creating or lifting a digest revocation retires every record instead of a named one, because a digest identifies bytes rather than a repository resource and no index maps it back to the resources that publish it. An operation that changes no decision retires nothing.

Implementations

On this page