Xema Store API: schemas
The request and response bodies of the operations in this API.
BiomeCategory
Section this listing is filed under, DERIVED from the biome manifest. Null means not filed yet — a storefront renders those together rather than inventing a section for them.
Type: string (9 values)
BiomeLifecycle
Store-scoped lifecycle. Only store-submitted, store-approved, and archived are reachable from this service.
Type: one of "draft", "sandbox-installed", "review-required", "org-installed", "store-submitted", "store-approved", "archived"
BiomeTrustTier
Provenance tier — primary input to the install consent flow.
Type: one of "system", "first-party", "verified-store", "community-store", "private-org", "generated-sandbox"
CommentListingVersionDto
| Property | Type | Required | Description |
|---|---|---|---|
notes | string | yes |
CreateStoreListingDto
| Property | Type | Required | Description |
|---|---|---|---|
biomeId | string | yes | |
category | BiomeCategory | no | The manifest-derived section. Accepted on CREATE because the reconciler carries it from the manifest; deliberately absent from UpdateStoreListingDto, because re-filing a biome is a manifest change and a second authored copy is the drift the derived/editorial split exists to prevent. |
description | string | yes | |
displayName | string | yes | |
pricingPolicy | StorePricingPolicyDto | no | Omitted ≡ free. Validated strictly against PricingPolicySchema (400 STORE_LISTING_PRICING_POLICY_INVALID on violation). |
publisher | string | no | PRODUCER-STATED, and REQUIRED for scope: global — resolved from the trust anchor that verified the bundle. REFUSED for scope: org (400 STORE_LISTING_PROVENANCE_NOT_ACCEPTED), where it is the authenticated org. |
revenueShare | StoreRevenueShareDto | no | Store-side revenue-share config. Validated strictly against RevenueShareSchema (400 STORE_LISTING_REVENUE_SHARE_INVALID). |
scope | StoreScope | yes | |
trustTier | BiomeTrustTier | no | PRODUCER-STATED, and REQUIRED for scope: global — resolved from the distribution lock's biome tier. REFUSED for scope: org (400 STORE_LISTING_PROVENANCE_NOT_ACCEPTED), where it is always private-org: nobody reviewed the biome. |
PaginationMeta
| Property | Type | Required | Description |
|---|---|---|---|
hasMore | boolean | no | |
limit | number | no | |
nextCursor | string or null | no | |
page | number | no | |
previousCursor | string or null | no | |
total | number | no | |
totalPages | number | no |
PricingPolicyKind
free = no license is needed. licensed = the listing is sold under the billing entitlement named by entitlementKey. The Store lists and licenses; installation is performed by the platform.
Type: one of "free", "licensed"
ProblemActionableBy
Who can act on this refusal: user (correct the input, sign in), org-admin (an administrator of the organisation), platform (the operators of this installation), none (nobody — it cannot succeed). ABSENT when not known; never guessed.
Type: one of "user", "org-admin", "platform", "none"
ProblemDetailsDto
RFC 9457 problem document. The declared members are the reserved core; extension members are TOP-LEVEL and OPEN, owned by the refusing plane.
| Property | Type | Required | Description |
|---|---|---|---|
actionableBy | ProblemActionableBy | no | Who can act on this refusal: user (correct the input, sign in), org-admin (an administrator of the organisation), platform (the operators of this installation), none (nobody — it cannot succeed). ABSENT when not known; never guessed. |
code | string | yes | SCREAMING_SNAKE_CASE. The machine-branchable refusal, and the value a policy rule, a retry predicate and a UI branch all name. |
detail | string | no | Human-readable and specific to THIS occurrence. |
errors | array of ProblemFieldIssueDto | no | Field-level issues, when the refusal is about the request body. |
instance | string | no | URI reference identifying the occurrence — a request path, a run, a row. |
params | map of string or number or boolean | no | Safe i18n interpolation values for the message keyed by code — typed and allowlisted per code by its declaration. Never server-authored copy, never internal diagnostics. |
retry | ProblemRetry | no | What a retry can achieve: transient (later, unchanged), after-change (only after someone changes something), never (a defect until a fixed version ships). ABSENT when not known. |
status | number | yes | The HTTP status code, repeated in the body so a logged document is self-contained. |
title | string | yes | Short, human-readable, and STABLE for a given type. Never per-occurrence — that is detail. |
traceId | string | no | W3C trace-context trace-id, present when the caller sent a traceparent. Omitted rather than invented when it did not. |
type | string | yes | Absolute URI identifying the refusal TYPE. Derived one-to-one from code, so a caller may branch on either and can never be told two different things. Never about:blank. |
ProblemFieldIssueDto
| Property | Type | Required | Description |
|---|---|---|---|
code | string | no | SCREAMING_SNAKE_CASE code of THIS issue, for a frontend i18n key. Present when the issue was minted by a declared problem. |
detail | string | yes | Prose for logs and developers. A frontend localises from code + params instead. |
params | map of string or number or boolean | no | Safe i18n interpolation values for this issue's code. |
pointer | string | yes | RFC 6901 JSON Pointer into the request body. Root is "/". |
ProblemRetry
What a retry can achieve: transient (later, unchanged), after-change (only after someone changes something), never (a defect until a fixed version ships). ABSENT when not known.
Type: one of "transient", "after-change", "never"
ProvenanceVerdict
Supply-chain provenance verdict captured at submit time.
Type: one of "VALID", "INVALID", "MISSING"
SignatureVerdict
Supply-chain signature verdict captured at submit time.
Type: one of "VALID", "INVALID", "UNSIGNED"
StagedUploadSlotDto
| Property | Type | Required | Description |
|---|---|---|---|
contentType | string | yes | Content type pinned into the signature. |
expiresAt | string (date-time) | yes | When the presigned URL stops being accepted. |
putUrl | string | yes | Presigned URL to PUT the .tgz to. Expires; mint another rather than caching it. |
requiredHeaders | map of string | yes | Headers that MUST be sent verbatim with the PUT. The backend signs Content-Type into the canonical request, so altering or dropping these fails the signature check rather than producing a useful error. |
uploadId | string | yes | Opaque handle for the staged object. Pass back as the submission's stagedUploadId — do not parse it. |
StagedUploadSlotDtoDataEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | StagedUploadSlotDto | yes |
StoreLicenseDto
| Property | Type | Required | Description |
|---|---|---|---|
entitlementKey | string | yes | The EFFECTIVE billing entitlement recorded when the license was issued (the selected plan’s per-tier key when set, else the policy-level key). |
id | string | yes | |
installId | string or null | no | The install that issued this license (null if detached). |
issuedAt | string (date-time) | yes | |
issuedById | string | yes | |
listingId | string | yes | |
listingVersionId | string | yes | |
orgId | string | yes | |
plan | string or null | no | Selected plan tier id, or null when no named tier was chosen. |
revokedAt | string (date-time) or null | no | |
revokedById | string or null | no | |
status | StoreLicenseStatus | yes | active = currently held. revoked = admin-revoked. |
StoreLicenseDtoDataEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | StoreLicenseDto | yes |
StoreLicenseDtoPaginatedEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | array of StoreLicenseDto | yes | |
pagination | PaginationMeta | yes |
StoreLicenseStatus
active = currently held. revoked = admin-revoked.
Type: one of "active", "revoked"
StoreListingDto
| Property | Type | Required | Description |
|---|---|---|---|
archived | boolean | yes | |
biomeId | string | yes | The biome's canonical id (e.g. 'document-buddy'). |
category | BiomeCategory or null | no | Section this listing is filed under, DERIVED from the biome manifest. Null means not filed yet — a storefront renders those together rather than inventing a section for them. |
createdAt | string (date-time) | yes | |
description | string | yes | |
descriptionOverridden | boolean | yes | As displayNameOverridden, for the description. |
displayName | string | yes | |
displayNameOverridden | boolean | yes | True when displayName above is the operator OVERRIDE rather than the reconciled text. The console shows "overridden from manifest"; clearing the override (PATCH with null) reverts. |
featured | boolean | yes | Operator-curated featured flag. The storefront shelf reads THIS, not a trust-tier proxy. |
id | string | yes | |
latestVersion | string or null | yes | Version string of the newest PUBLISHED (store-approved) version, ordered by submittedAt desc — the same ordering the versions endpoint uses. null when the listing has no approved version yet. |
orgId | string or null | no | Tenancy/visibility scope: the owning org's id when scope = org; null for global listings. NOT the publisher — see publisherOrgId. |
pricing | StorePricingSummaryDto | yes | Derived storefront pricing summary (kind + badge + plans). Always present — a storefront badges + renders tiers from this without touching the raw policy. |
pricingPolicy | StorePricingPolicyDto or null | yes | Typed pricing policy, or null when the listing is unpriced (null ≡ free). Storefronts badge kind = licensed listings. The Store does not install; installation is performed by the platform. Prefer the derived pricing summary for badging. |
publicationState | StorePublicationState | yes | Whether this deployment shows the listing. Distinct from archived, which is a lifecycle terminal — withholding is reversible. |
publisher | string | yes | |
publisherOrgId | string or null | no | Provenance: the org that PUBLISHED this listing. Set for BOTH scope = org and scope = global rows and derived server-side from the authenticated publisher org at create time (never client-supplied). Null ONLY on legacy global listings created before the column existed, whose publisher org is unknowable and which an org erasure therefore reports as unattributable instead of silently skipping. |
revenueShare | StoreRevenueShareDto or null | yes | Store-side revenue-share config, or null when none is set. Records the publisher payout split; the actual settlement is a billing-api follow-up (the Store only persists the config). |
scope | StoreScope | yes | Catalog scope. Global = cross-org; Org = single-org catalog. |
sortWeight | number | yes | Operator ordering weight; higher sorts first. |
trustTier | BiomeTrustTier | yes | Provenance tier — primary input to the install consent flow. |
updatedAt | string (date-time) | yes |
StoreListingDtoDataEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | StoreListingDto | yes |
StoreListingDtoPaginatedEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | array of StoreListingDto | yes | |
pagination | PaginationMeta | yes |
StoreListingVersionDto
| Property | Type | Required | Description |
|---|---|---|---|
approvedAt | string (date-time) or null | no | |
approvedById | string or null | no | |
archivedAt | string (date-time) or null | no | |
bundleSha | string or null | no | |
bundleUri | string or null | no | |
compatibilityEvidence | object | yes | |
contentHash | string | yes | Immutable canonical content hash for this authored revision. |
dependencies | array of object | yes | Owner-qualified dependency targets published with this revision. |
hostContractVersion | string or null | no | Host-contract version the web remote was built against. |
id | string | yes | |
lifecycle | BiomeLifecycle | yes | Store-scoped lifecycle. Only store-submitted, store-approved, and archived are reachable from this service. |
listingId | string | yes | |
manifestSnapshot | object | yes | Frozen BiomeManifest at submission time. |
notes | string or null | no | |
permissionDigest | object | yes | Canonical digest derived from requiresCapabilities + exposesCapabilities. |
provenanceVerdict | ProvenanceVerdict or null | no | Supply-chain provenance verdict captured at submit time. |
releasePolicyEvidence | object | yes | |
releaseRequestId | string or null | no | |
releaseRequestStatus | string or null | no | |
signatureVerdict | SignatureVerdict or null | no | Supply-chain signature verdict captured at submit time. |
submittedAt | string (date-time) | yes | |
version | string | yes | |
webExposedModule | string or null | no | BARE exposed-module key the host loads from the container (e.g. biome). Carries no ./ prefix — loadRemote takes <container>/<key>. |
webIntegrity | string or null | no | Sub-resource integrity of the remote-entry artifact. |
webRemoteEntryUrl | string or null | no | REMOTE_FEDERATED remote-entry URL (target:web biomes). |
webRemoteName | string or null | no | Module-Federation container name the built remote self-registers under (e.g. grants_web_remote). NOT the npm package name. |
StoreListingVersionDtoDataArrayEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | array of StoreListingVersionDto | yes |
StoreListingVersionDtoDataEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | StoreListingVersionDto | yes |
StorePlanDto
| Property | Type | Required | Description |
|---|---|---|---|
displayName | string | yes | |
entitlementKey | string | no | Per-tier billing feature-flag. When set, selecting this plan gates the install on THIS key instead of the policy-level entitlementKey. When omitted the plan inherits the policy-level entitlementKey. |
id | string | yes | Stable, per-policy-unique plan id the install references. |
priceHint | string | no | Advisory price label (e.g. "$29/mo"). NOT an enforcement input; its presence flips the storefront badge from licensed to paid. |
StorePricingBadge
Storefront badge. free = no policy / kind=free. licensed = entitlement-gated, no displayed price. paid = licensed AND at least one plan carries a priceHint.
Type: one of "free", "licensed", "paid"
StorePricingPolicyDto
| Property | Type | Required | Description |
|---|---|---|---|
entitlementKey | string | no | billing-api feature-flag name that entitles an org to the listing. Required when kind = licensed; forbidden when kind = free. |
kind | PricingPolicyKind | yes | free = no license is needed. licensed = the listing is sold under the billing entitlement named by entitlementKey. The Store lists and licenses; installation is performed by the platform. |
plan | string | no | Advisory storefront metadata: which plan grants the entitlement. NOT an enforcement input. Only allowed when kind = licensed. |
plans | array of StorePlanDto | no | Named plan tiers (phase 2). Optional — pre-phase-2 policies parse unchanged. An install selects one via planId; a per-tier entitlementKey overrides the policy-level key for that tier. Only allowed when kind = licensed. |
StorePricingSummaryDto
| Property | Type | Required | Description |
|---|---|---|---|
badge | StorePricingBadge | yes | Storefront badge. free = no policy / kind=free. licensed = entitlement-gated, no displayed price. paid = licensed AND at least one plan carries a priceHint. |
kind | PricingPolicyKind | yes | Policy kind (free | licensed). free for unpriced listings. |
plans | array of StorePlanDto | no | Named plan tiers, when the licensed policy declares them. |
StorePublicationState
Whether this deployment shows the listing. Distinct from archived, which is a lifecycle terminal — withholding is reversible.
Type: one of "published", "withheld"
StoreRevenueShareDto
| Property | Type | Required | Description |
|---|---|---|---|
publisherAccountRef | string | yes | The payee's billing Account.externalRef. Resolved by the future settlement job against billing-api; the Store only persists it. |
sharePercent | number | yes | The publisher's cut, 0–100 inclusive (≤2 decimals). Stored verbatim; the Store never applies it. |
StoreReviewAction
Type: one of "submit", "approve", "reject", "archive", "comment"
StoreReviewLogEntryDto
| Property | Type | Required | Description |
|---|---|---|---|
action | StoreReviewAction | yes | |
actorId | string | yes | |
createdAt | string (date-time) | yes | |
id | string | yes | |
listingVersionId | string | yes | |
notes | string or null | no |
StoreReviewLogEntryDtoDataArrayEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | array of StoreReviewLogEntryDto | yes |
StoreScope
Catalog scope. Global = cross-org; Org = single-org catalog.
Type: one of "global", "org"
SubmitListingVersionDto
| Property | Type | Required | Description |
|---|---|---|---|
bundleSha | string | no | Integrity hash of the bundle. Optional at Phase 8. |
bundleUri | string | no | Where the biome bundle is fetched from (OCI ref or git+ref). Stored as a placeholder at Phase 8. |
compatibilityEvidence | object | yes | Compatibility evaluation inputs frozen with this immutable package revision. |
dependencies | array of object | yes | Owner-qualified RevisionTarget dependency intents resolved atomically by the generic release plane. |
manifestSnapshot | object | yes | Full BiomeManifest document (xema-biome.json). |
notes | string | no | |
releasePolicyEvidence | object | yes | Release policy inputs frozen with this immutable package revision. |
stagedUploadId | string | no | Handle of a bundle staged through POST /listings/:id/versions/staging (Grow plane A1). Opaque — pass back exactly what the staging response returned. REQUIRES bundleSha: staging and fetching are two moments, and every verdict downstream is computed over whatever bytes arrive, so a staged submission with no digest is bytes nothing can bind a verdict to. Distinct from bundleUri, which is an OCI or git ref. |
version | string | yes | Semver version. Unique within the listing. |
webArtifact | SubmitWebArtifactDto | no | REMOTE_FEDERATED web-artifact facts for a target:web biome. Omit for server biomes. |
SubmitListingVersionResponseDto
| Property | Type | Required | Description |
|---|---|---|---|
approvedAt | string (date-time) or null | no | |
approvedById | string or null | no | |
archivedAt | string (date-time) or null | no | |
bundleSha | string or null | no | |
bundleUri | string or null | no | |
compatibilityEvidence | object | yes | |
contentHash | string | yes | Immutable canonical content hash for this authored revision. |
dependencies | array of object | yes | Owner-qualified dependency targets published with this revision. |
hostContractVersion | string or null | no | Host-contract version the web remote was built against. |
id | string | yes | |
lifecycle | BiomeLifecycle | yes | Store-scoped lifecycle. Only store-submitted, store-approved, and archived are reachable from this service. |
listingId | string | yes | |
manifestSnapshot | object | yes | Frozen BiomeManifest at submission time. |
notes | string or null | no | |
permissionDigest | object | yes | Canonical digest derived from requiresCapabilities + exposesCapabilities. |
provenanceVerdict | ProvenanceVerdict or null | no | Supply-chain provenance verdict captured at submit time. |
releasePolicyEvidence | object | yes | |
releaseRequestId | string or null | no | |
releaseRequestStatus | string or null | no | |
signatureVerdict | SignatureVerdict or null | no | Supply-chain signature verdict captured at submit time. |
submittedAt | string (date-time) | yes | |
version | string | yes | |
webExposedModule | string or null | no | BARE exposed-module key the host loads from the container (e.g. biome). Carries no ./ prefix — loadRemote takes <container>/<key>. |
webIntegrity | string or null | no | Sub-resource integrity of the remote-entry artifact. |
webRemoteEntryUrl | string or null | no | REMOTE_FEDERATED remote-entry URL (target:web biomes). |
webRemoteName | string or null | no | Module-Federation container name the built remote self-registers under (e.g. grants_web_remote). NOT the npm package name. |
SubmitListingVersionResponseDtoDataEnvelope
| Property | Type | Required | Description |
|---|---|---|---|
data | SubmitListingVersionResponseDto | yes |
SubmitWebArtifactDto
| Property | Type | Required | Description |
|---|---|---|---|
exposedModule | string | yes | BARE exposed-module key the host loads from the container (e.g. biome). Module Federation loadRemote takes <container>/<key>, so the key carries NO ./ prefix — the host composes the specifier itself. There is exactly ONE spelling on the wire. |
hostContractVersion | string | yes | Host-contract version the remote was built against. |
integrity | string | yes | Sub-resource integrity hash of the remote-entry artifact. |
provenanceRef | string | no | SLSA provenance attestation reference (relative filename alongside the remote-entry, or an absolute URL). The provenanceVerdict is computed server-side, not client-trusted. |
remoteEntry | string | yes | Module-Federation remote-entry URL (remoteEntry.js). |
remoteName | string | yes | Module-Federation CONTAINER name the built remote self-registers under at runtime (e.g. grants_web_remote for biome id grants-web). This is NOT the npm package name — the two are unrelated strings, and substituting the package name yields a container the host can never resolve. Carried end-to-end from the publish descriptor to the host loader and NEVER re-derived. |
signatureBundleRef | string | no | Sigstore signature bundle for remoteEntry.js (relative filename alongside the remote-entry, or an absolute URL). The store verifies it server-side with cosign — the resulting signatureVerdict is NOT client-trusted. |
UpdateStoreListingDto
| Property | Type | Required | Description |
|---|---|---|---|
description | string or null | no | Override the reconciled description. Explicit null clears the override. Omitted = unchanged. |
displayName | string or null | no | Override the reconciled display name. Explicit null CLEARS the override, so the listing falls back to the distribution-plane text — that is what "revert to the manifest" means here. Omitted = unchanged. |
featured | boolean | no | Curated featured flag — what the storefront shelf reads. |
pricingPolicy | StorePricingPolicyDto or null | no | Replace the pricing policy. Explicit null clears it back to unpriced (≡ free). Omitted = unchanged. Validated strictly against PricingPolicySchema (400 STORE_LISTING_PRICING_POLICY_INVALID). |
publicationState | StorePublicationState | no | Withhold or publish this listing IN THIS DEPLOYMENT. Not archival. Archiving is a lifecycle terminal gated on store:biome.archive@1; this is reversible and local, which is what an operator curating a catalog actually needs. |
revenueShare | StoreRevenueShareDto or null | no | Replace the revenue-share config. Explicit null clears it. Omitted = unchanged. Validated strictly against RevenueShareSchema (400 STORE_LISTING_REVENUE_SHARE_INVALID). |
sortWeight | number | no | Operator ordering weight; higher sorts first. |