Skip to content
LogoLogo

Workspace Schema Endpoint

A JSON Schema document for the structure of your project: content models, fields, feature keys, experience keys, and step keys. Tooling reads this endpoint to generate TypeScript types for your application.

Request

GET /api/v1/projects/:projectId/schema
ParameterInDescription
projectIdpathThe project whose schema to fetch.
preview_tokenqueryOptional. Returns the preview (unpublished) schema when you send it.

Response

The response is a JSON Schema draft 2020-12 document with Picked-specific extension fields:

FieldDescription
x-picked-schema-versionSchema document version (currently 1).
x-picked-source"published" or "preview" — mirrors the surface you requested.
x-picked-version-idPublished workspace version id, or null on preview.
x-picked-step-content-modelsMap of step key → content model key, which gives each layout its type.
x-picked-feature-valuesMap of feature key → the values that the feature can serve. Picked adds this field only when the workspace has a Text feature flag.
$defs.contentModelsJSON Schema definitions for each content model.
$defs.contentBlocksJSON Schema definitions for reusable content blocks.
$defs.fieldsObject schema for project field values.
$defs.featureKeysString enum of feature keys.
$defs.experienceKeysString enum of experience keys.
$defs.stepKeysString enum of step keys.

Field values

Each content model and content block definition describes a field value in the form that the Delivery API serves it:

Field typeValue
assetOne of two objects. A resolved asset has id, url, mimeType, sizeBytes, fileName, width, and height. width and height are null for a file that is not an image. An asset that does not exist, or that you deleted, has id, and versionId when the reference holds a version.
html-assetid and content. content is the text of the file, or null when Picked cannot read the file.
content-blockOne of the block definitions in $defs.contentBlocks that the field accepts: a $ref, or a oneOf of $refs. A field with a category accepts the blocks of that category. A field with no category accepts all blocks. Each block definition has contentBlockId, contentBlockKey, and data. contentBlockKey is a const that holds the key of the block.
referencecontentEntryId. The value can also have contentModelKey and data. It has data only when the API resolves the entry. A reference that is too deep, or that makes a cycle, can have contentModelKey and no data.

The Delivery API does not serve a block that no longer exists, for example a block that you deleted. A repeatable content-block field does not include the block in its list. A content-block field that is not repeatable is not in the data of the entry.

A published schema keeps the value shapes that it had when you published the workspace. The preview schema always has the shapes in this table.

Published and preview

On the published surface, the schema reflects your last published workspace. On the preview surface (?preview_token=...), the schema reflects the current draft workspace. See Preview, cache, and crawlers.

When no published schema exists, the published endpoint returns 404 and tells you to publish the workspace.

A Boolean feature flag serves true or false, and it contributes no entry to x-picked-feature-values. A workspace of Boolean feature flags therefore omits the field. A schema that Picked published before Text feature flags existed also omits it.

Picked sorts the values of each Text feature flag by the key of the variant. The document therefore does not change when you rename a variant or move a row.

Example

curl https://api.picked.app/api/v1/projects/proj_123/schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "picked:project/proj_123/schema",
  "x-picked-schema-version": 1,
  "x-picked-source": "published",
  "x-picked-version-id": "ver_456",
  "x-picked-step-content-models": {
    "intro": "welcome-page"
  },
  "x-picked-feature-values": {
    "hero": [false, "hero-a", "hero-b"]
  },
  "$defs": {
    "contentModels": {},
    "contentBlocks": {},
    "fields": { "type": "object", "additionalProperties": false, "properties": {} },
    "featureKeys": { "type": "string", "enum": ["default", "hero"] },
    "experienceKeys": { "type": "string", "enum": ["welcome-survey"] },
    "stepKeys": { "type": "string", "enum": ["intro"] }
  }
}