| name | schema-manager |
| description | Browse and modify schema fields, mappings, identity config, and field rankings. Use when the user wants to list, view, create, or modify schema fields, mappings, identity configuration, or field rankings. |
| metadata | {"arguments":"action and relevant parameters -- list-fields, get-field, create-field, list-mappings, create-mapping, publish"} |
Schema Manager
Purpose
Browse and modify the profile schema -- fields, mappings, identity configuration, and field rankings. Use this when users want to understand their data model, add new fields, or modify field mappings.
Environment
Requires authenticated API access. See ../references/auth.md for credential resolution.
API Endpoints
Schema Overview
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Fields
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/field" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/fieldnames" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/field/${FIELD_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/field" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"Field": "field_name",
"Type": "string",
"ShortDesc": "Brief description",
"MergeOp": "latest",
"IsIdentifier": false,
"IsPII": false
}'
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/field/${FIELD_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"Field": "field_name",
"Type": "string",
"ShortDesc": "Updated description",
"MergeOp": "latest",
"IsIdentifier": true,
"IsPII": false
}'
curl -s -X DELETE "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/field/${FIELD_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Mappings
A mapping connects a source stream field to a target schema field via an LQL expression. A field without at least one mapping is inert -- it will never receive data.
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/mapping" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/mapping/${MAPPING_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/mapping" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"field": "email",
"stream": "default",
"expr": "email(email_address)"
}'
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/mapping" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"field": "hashed_email",
"stream": "click_stream",
"expr": "hash.sha256(email(email))",
"guard_expr": "email != '\'\''"
}'
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/mapping/${MAPPING_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"field": "email",
"stream": "new_stream",
"expr": "email(raw_email)"
}'
curl -s -X DELETE "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/mapping/${MAPPING_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Mapping payload fields:
| Field | Required | Description |
|---|
field | YES | Target schema field name -- must reference an existing field |
stream | YES | Source stream name (e.g., default, salesforce_contacts) |
expr | YES | LQL expression to extract/transform the value (e.g., set(raw_field), email(email_address)) |
guard_expr | No | Optional condition controlling when this mapping applies (do not prefix with "IF") |
Common LQL expressions for mappings:
- Simple pass-through:
raw_field_name
- Set/array:
set(raw_field)
- Email normalization:
email(email_address)
- Hashing:
hash.sha256(email(email))
- URL parsing:
url(page_url)
- Type casting:
todate(timestamp_field)
Schema Patches
Schema patches group related changes into a named changeset that can be reviewed and applied together -- like a git branch for schema changes. Accounts with enable_schema_patches: true must use patches for all schema changes. See "Determining the Write Workflow" in the Behavior section.
Patch lifecycle: Create patch -> Add changes -> Review diff -> Apply
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"tag": "add-purchase-fields",
"description": "Add purchase tracking fields and mappings for Shopify integration"
}'
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"description": "Updated description"}'
curl -s -X DELETE "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/apply" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Add fields to a patch:
Patch endpoint payload shape is lowercase. Use id (the field name), type, shortdesc, mergeop, is_identifier, is_pii. The capitalized shape (Field, Type, ShortDesc, ...) shown in the non-patch direct-write examples below is NOT accepted here -- patch endpoints will return Attribute 'Field' is required for Field if you send capitalized keys.
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/field" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"id": "purchase_total",
"type": "number",
"shortdesc": "Total purchase amount",
"mergeop": "sum",
"is_identifier": false,
"is_pii": false
}'
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/field/${FIELD_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{ ... full field definition ... }'
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/field/${FIELD_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Add mappings to a patch:
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/mapping" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"field": "purchase_total",
"stream": "shopify_orders",
"expr": "total_price"
}'
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/mapping/${MAPPING_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{ ... mapping definition ... }'
Add rank changes to a patch:
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/${TABLE}/${PATCH_ID}/rank" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{ ... rank config ... }'
Edit statuses within a patch:
| Status | Meaning |
|---|
new | Does not exist in live schema -- will be created |
modified | Exists in live schema -- properties have been changed |
deleted | Marked for removal when patch is applied |
unmodified | Included for context, no changes from live |
Identity Configuration
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/idconfig" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Field Rankings
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/rank" \
-H "Authorization: ${LYTICS_API_TOKEN}"
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/rank" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{ ... ranking config ... }'
Publish Schema Changes
Publish requires a tag and description. Both are mandatory.
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/publish" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"tag": "short-kebab-tag",
"description": "Human-readable description of what changed"
}'
The tag should be a short kebab-case identifier (e.g., add-phone-identifier). The description should explain the changes for audit purposes.
Generate LQL from Schema
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/lql" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{ ... schema config ... }'
Field Types
See ../references/field-types.md for the complete type reference including:
- Scalar:
string, bool, int, number, date
- Complex:
[]string, map[string]int, map[string]string, etc.
- Special:
geolocation, embedding, membership
Behavior
For Read Operations (list, get, browse)
Execute immediately. Present fields in a readable table format showing:
- Field name, type, description, merge operation, identity/PII flags
Determining the Write Workflow
Some accounts require schema patches (account setting enable_schema_patches: true). Others use the direct publish workflow. You must determine which mode the account uses before making any schema changes.
Check by attempting to list patches:
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/patch/user" \
-H "Authorization: ${LYTICS_API_TOKEN}"
If this returns successfully (even an empty list), the account uses patches. If it returns an error or 404, use the direct publish workflow.
Write Workflow A: Schema Patches (when enabled)
When the account has schema patches enabled, all schema changes must go through patches. Direct field/mapping edits will not work.
Complete workflow for adding a new field with mapping:
- Create a patch with a descriptive name
- Add the field to the patch
- Add a mapping for the field to the patch -- a field without a mapping is inert and will never receive data. Always ask: "Which stream should populate this field, and what is the source field name?"
- Review the patch diff (GET the patch to see all changes vs live schema)
- Confirm with the user (show the diff summary)
- Apply the patch (this publishes a new schema version)
If the user doesn't know the stream name, list available streams:
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/stream/names" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Write Workflow B: Direct Publish (when patches are not enabled)
When the account does not use schema patches, edits go into a shared unpublished draft and must be published manually.
Schema changes are staged until published -- they do not take effect until you publish.
When creating a new field, always prompt for a mapping -- a field without a mapping is inert. Then publish both together.
Every write operation MUST follow this sequence:
- Confirm: Use the confirmation-gate pattern. Show what will change and get user approval.
- Execute: Make the field/mapping change via the API.
- Publish: Immediately publish the changes. A schema write is NOT complete until publish succeeds.
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/${TABLE}/publish" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"tag": "descriptive-tag", "description": "What changed and why"}'
- Verify: Confirm publish succeeded. If it fails, report the error -- the changes are still staged and need to be published before they take effect.
Never consider a schema write operation complete without publishing. If multiple changes are being made in sequence, you may batch them and publish once at the end, but always publish before reporting success.
Error Handling
- Field already exists (409): Show existing field details, ask if user wants to update instead
- Invalid type: List valid types from
../references/field-types.md
- Publish failures: Show error details, suggest checking field validity
Dependencies
- Uses:
../references/auth.md, ../references/api-client.md, ../references/confirmation-gate.md
- References:
../references/field-types.md