Skip to content
EntryLayer Operational data entry for Snowflake

SQL Procedures and Functions

These SQL objects are called in Snowsight (or any SQL client) to manage the installed EntryLayer Native App. The public admin surface is exposed through the ENTRYLAYER.API schema.

  • Procedure examples use ENTRYLAYER as the installed app name. Replace it when your Native App is installed under a different name.
  • VARIANT responses use the standard envelope. Check status before reading data; when status = 'error', use code and message.
  • Contract snippets show response shape and may include symbolic placeholders such as Project, Field, or FormVersion.
  • Draft, form design, validation, and rule changes are not visible to end users until PUBLISH_PROJECT_DRAFT succeeds.
  • Source discovery commands are metadata-only. They do not sample source rows or send customer data to provider-owned services.

Use these workflow groups when browsing the procedure catalog.

FamilyUse it for
Discovery & Agent GuidanceLoad help, contracts, and structured agent metadata.
Source Discovery & PreviewInspect caller-visible Snowflake metadata without sampling rows.
Project Lifecycle & SettingsCreate, inspect, update, archive, restore, and organize projects.
Drafts & VersionsInspect drafts, save/publish/discard drafts, and manage form versions.
Form Design & ValidationCreate sections, rows, fields, validations, primary keys, and Variant-derived fields.
Form RulesGenerate, create, update, disable, and delete form logic rules.
WorkflowInspect and replace workflow configuration or apply templates.
RelationshipsManage parent/child project relationships.
FoldersOrganize projects into folders.
AccessManage EntryLayer project access and permissions.
Analytics & AuditInspect aggregate analytics and admin audit metadata.
Source ConfigurationInspect and reconfigure source metadata bindings.
Users & LicensingManage EntryLayer seats and user listings.
BillingPreview anonymous billing and billing ledger records.
OperationsSuspend or resume app-owned compute resources.
Extraction FunctionsRead published submission extracts and extract metadata.

The detailed reference below is grouped by workflow. Use this alphabetical index when you already know the object name.

Signature:

CALL ENTRYLAYER.API.HELP();

Returns: VARCHAR

Guidance:

Returns the full SQL API reference as markdown, including procedure signatures, available views, common workflows, and JSON parameter schemas.

Example:

CALL ENTRYLAYER.API.HELP();

HELP(topic VARCHAR)

Returns focused help for a command or topic. Command topics include VALIDATE_SOURCE, CREATE_PROJECT, GET_PROJECT, GET_PROJECT_LAYOUT, LIST_PROJECTS, GRANT_ACCESS, REVOKE_ACCESS, and LIST_ACCESS.

Command topics include every command name in APP_PUBLIC.API_REFERENCE, including procedures and functions.

Category topics include PROJECTS, FORM_DESIGN, DRAFTS, FIELDS, VALIDATIONS, RULES, WORKFLOW, WORKFLOW_TEMPLATES, SUBMISSIONS, RELATIONSHIPS, FOLDERS, SOURCE_CONFIG, SHARING, ACCESS, LICENSES, BILLING, OPERATIONS, DATA_EXTRACTION, WORKFLOWS, IDEMPOTENCY, SECURITY, CONTRACTS, JSON_SCHEMAS, SETUP, TROUBLESHOOTING, FIELD_TYPES, EXAMPLES, ERRORS, AGENT_MANIFEST, CORTEX_CODE, and CORTEX_SKILL.

Example:

CALL ENTRYLAYER.API.HELP('LIST_PROJECTS');

Signature:

CALL ENTRYLAYER.API.HELP(<topic>);

Parameters:

NameTypeDescription
topicVARCHARCommand or category name to inspect, for example CONTRACTS, CREATE_PROJECT, or CORTEX_CODE.

Returns: VARCHAR

Guidance:

Returns the full SQL API reference as markdown, including procedure signatures, available views, common workflows, and JSON parameter schemas.

Example:

CALL ENTRYLAYER.API.HELP();

HELP(topic VARCHAR)

Returns focused help for a command or topic. Command topics include VALIDATE_SOURCE, CREATE_PROJECT, GET_PROJECT, GET_PROJECT_LAYOUT, LIST_PROJECTS, GRANT_ACCESS, REVOKE_ACCESS, and LIST_ACCESS.

Command topics include every command name in APP_PUBLIC.API_REFERENCE, including procedures and functions.

Category topics include PROJECTS, FORM_DESIGN, DRAFTS, FIELDS, VALIDATIONS, RULES, WORKFLOW, WORKFLOW_TEMPLATES, SUBMISSIONS, RELATIONSHIPS, FOLDERS, SOURCE_CONFIG, SHARING, ACCESS, LICENSES, BILLING, OPERATIONS, DATA_EXTRACTION, WORKFLOWS, IDEMPOTENCY, SECURITY, CONTRACTS, JSON_SCHEMAS, SETUP, TROUBLESHOOTING, FIELD_TYPES, EXAMPLES, ERRORS, AGENT_MANIFEST, CORTEX_CODE, and CORTEX_SKILL.

Example:

CALL ENTRYLAYER.API.HELP('LIST_PROJECTS');

Signature:

CALL ENTRYLAYER.API.AGENT_MANIFEST();

Returns: VARIANT

Guidance:

Returns a structured VARIANT manifest for Snowsight Cortex and other SQL agents.

Success data contract:

{
"api_version": "v3",
"required_application_role": "ENTRYLAYER_ADMIN",
"first_call_sequence": [
...
],
"command_catalog": [
{
"command_name": "CREATE_PROJECT",
"family": "projects",
"policy": {
"read_only": false,
"idempotent": false,
"requires_publish": false,
"mutates_draft": false,
"invokes_cortex": false,
"source_metadata_only": false
}
}
],
"workflow_recipes": [
...
],
"guardrails": [
...
]
}

Required first-call sequence: HELP(), HELP(‘CONTRACTS’), HELP(‘SECURITY’), AGENT_MANIFEST().

Guardrail: The manifest is metadata only. It does not inspect customer sources, sample rows, invoke Cortex, or perform mutations.

Usage: load the manifest before composing SQL so Cortex can choose safe commands, understand retry/idempotency, and verify whether a command edits drafts or requires publish.

Example:

CALL ENTRYLAYER.API.AGENT_MANIFEST();

Signature:

CALL ENTRYLAYER.API.LIST_SOURCE_DATABASES();

Returns: VARIANT

Guidance:

Lists caller-visible databases that can be used as source-object roots.

Input contract: none.

Success data contract:

{
"databases": [
{
"name": "DB_NAME",
"kind": "DATABASE"
}
]
}

Guardrail: Metadata only. This does not inspect tables, sample rows, or grant access.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_SOURCE_DATABASES();

Signature:

CALL ENTRYLAYER.API.LIST_SOURCE_SCHEMAS(<database_name>);

Parameters:

NameTypeDescription
database_nameVARCHARSnowflake database name visible to the caller through caller rights.

Returns: VARIANT

Guidance:

Lists caller-visible schemas in an unquoted database name.

Input contract: database_name VARCHAR = unquoted Snowflake database identifier.

Success data contract:

{
"database": "DB_NAME",
"schemas": [
{
"name": "SCHEMA_NAME"
}
]
}

Guardrail: Metadata only. INFORMATION_SCHEMA is hidden from results.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_SOURCE_SCHEMAS('FINANCE_DB');

Signature:

CALL ENTRYLAYER.API.LIST_SOURCE_OBJECTS(<database_name>, <schema_name>, <options>);

Parameters:

NameTypeDescription
database_nameVARCHARSnowflake database name visible to the caller through caller rights.
schema_nameVARCHARSnowflake schema name visible to the caller through caller rights.
optionsVARIANTReserved metadata-listing options; pass an empty object when no filter is needed.

Returns: VARIANT

Guidance:

Lists caller-visible TABLE, VIEW, and SEMANTIC_VIEW objects in a schema.

Input contract: database_name VARCHAR, schema_name VARCHAR, options VARIANT reserved for future filters. Current behavior returns TABLE, VIEW, and SEMANTIC_VIEW objects.

Success data contract:

{
"database": "DB",
"schema": "SCHEMA",
"objects": [
{
"name": "OBJECT",
"type": "TABLE | VIEW | SEMANTIC_VIEW"
}
]
}

Guardrail: Metadata only. Use DESCRIBE_SOURCE or VALIDATE_SOURCE before CREATE_PROJECT.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_SOURCE_OBJECTS('FINANCE_DB', 'BILLING', PARSE_JSON('{}'));

Signature:

CALL ENTRYLAYER.API.LIST_SEMANTIC_VIEWS(<database_name>, <schema_name>);

Parameters:

NameTypeDescription
database_nameVARCHARSnowflake database name visible to the caller through caller rights.
schema_nameVARCHARSnowflake schema name visible to the caller through caller rights.

Returns: VARIANT

Guidance:

Lists caller-visible semantic views in a schema.

Input contract: database_name VARCHAR, schema_name VARCHAR = unquoted identifiers.

Success data contract:

{
"database": "DB",
"schema": "SCHEMA",
"semantic_views": [
{
"name": "VIEW_NAME",
"type": "SEMANTIC_VIEW"
}
]
}

Guardrail: Metadata only. Semantic-view columns are returned by DESCRIBE_SOURCE.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_SEMANTIC_VIEWS('FINANCE_DB', 'ANALYTICS');

Signature:

CALL ENTRYLAYER.API.VALIDATE_SOURCE(<source_object>);

Parameters:

NameTypeDescription
source_objectVARCHARFully qualified Snowflake source object name in DB.SCHEMA.OBJECT form; metadata-only operations never sample rows.

Returns: VARIANT

Guidance:

Checks whether the caller has restricted-caller access to a fully qualified table, view, or semantic view and returns column metadata.

The procedure does not sample source rows and is useful before CREATE_PROJECT when diagnosing grants or object-name typos.

For semantic views, the helper tries table/view metadata first and then falls back to DESCRIBE SEMANTIC VIEW.

Parameters:

  • source_object: unquoted DB.SCHEMA.OBJECT name.

Input contract: source_object VARCHAR = unquoted fully qualified DB.SCHEMA.OBJECT.

Success data contract:

{
"source_object": "DB.SCHEMA.OBJECT",
"source_type": "table | semantic_view",
"columns": [
SourceColumn
]
}

SourceColumn contract:

{
"name": "COL",
"type": "VARCHAR",
"nullable": true,
"comment": "",
"primary_key": false,
"default": null
}

. Semantic views return DIMENSION, FACT, METRIC, and DERIVED_METRIC DATA_TYPE rows as SourceColumn objects.

Guardrail: Use this before CREATE_PROJECT to catch grant or object-name issues. Do not request row samples.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.VALIDATE_SOURCE('FINANCE_DB.BILLING.UNPAID_INVOICES');

Signature:

CALL ENTRYLAYER.API.DESCRIBE_SOURCE(<source_object>);

Parameters:

NameTypeDescription
source_objectVARCHARFully qualified Snowflake source object name in DB.SCHEMA.OBJECT form; metadata-only operations never sample rows.

Returns: VARIANT

Guidance:

Alias for VALIDATE_SOURCE. Returns metadata for a table, view, or semantic view without source row values.

Input contract: source_object VARCHAR = unquoted fully qualified DB.SCHEMA.OBJECT.

Success data contract:

{
"source_object": "DB.SCHEMA.OBJECT",
"source_type": "table | semantic_view",
"columns": [
SourceColumn
]
}

Guardrail: Metadata only. Do not use SQL API source discovery for row sampling.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.DESCRIBE_SOURCE('FINANCE_DB.BILLING.UNPAID_INVOICES');

Signature:

CALL ENTRYLAYER.API.DESCRIBE_SOURCE_HIERARCHY(<source_object>, <options>);

Parameters:

NameTypeDescription
source_objectVARCHARFully qualified Snowflake source object name in DB.SCHEMA.OBJECT form; metadata-only operations never sample rows.
optionsVARIANTMetadata-only hierarchy discovery options; does not sample source rows.

Returns: VARIANT

Guidance:

Returns a metadata-only hierarchy shell for a source object so Cortex can reason about a root table before project generation.

Input contract: source_object VARCHAR = DB.SCHEMA.OBJECT; options VARIANT reserved for future filters.

Success data contract:

{
"source_object": "DB.SCHEMA.OBJECT",
"source_type": "table | semantic_view",
"tables": [
{
"name": "OBJECT",
"source_object": "DB.SCHEMA.OBJECT",
"columns": [
SourceColumn
]
}
],
"relationships": [
],
"warnings": [
]
}

Guardrail: This does not infer joins from source row data and does not create projects.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.DESCRIBE_SOURCE_HIERARCHY('FINANCE_DB.BILLING.UNPAID_INVOICES', PARSE_JSON('{}'));

Signature:

CALL ENTRYLAYER.API.PREVIEW_SOURCE_LAYOUT(<source_object>);

Parameters:

NameTypeDescription
source_objectVARCHARFully qualified Snowflake source object name in DB.SCHEMA.OBJECT form; metadata-only operations never sample rows.

Returns: VARIANT

Guidance:

Builds deterministic field templates from source metadata without creating a project, invoking Cortex, or sampling source rows.

Input contract: source_object VARCHAR = DB.SCHEMA.OBJECT.

Success data contract:

{
"source_object": "DB.SCHEMA.OBJECT",
"source_type": "table | semantic_view",
"layout": {
"sections": [
Section
]
},
"fields": [
FieldTemplate
]
}

Guardrail: Preview field ids are null because no registry rows are allocated until CREATE_PROJECT or CREATE_FIELD.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.PREVIEW_SOURCE_LAYOUT('FINANCE_DB.BILLING.UNPAID_INVOICES');

Signature:

CALL ENTRYLAYER.API.CREATE_EMPTY_PROJECT(<name>, <options>);

Parameters:

NameTypeDescription
nameVARCHARDisplay name for the new empty project.
optionsVARIANTProject options such as description and build settings; see the ProjectUpdates and SourceConfig contracts.

Returns: VARIANT

Guidance:

Creates a project with an empty draft so Cortex can build the form manually with section, row, field, validation, and rule procedures.

Input contract: name VARCHAR, options VARIANT =

{
"description": "string optional",
"workflow_enabled": false,
"auto_save_enabled": false,
"multi_step_enabled": false
}

Success data contract:

{
"project": Project,
"project_id": "proj_123",
"draft": FormVersion
}

Guardrail: No source object or sync config is created. Use RECONFIGURE_SOURCE later if a Snowflake source should back the project.

Idempotency: not idempotent. Each successful call creates a new project.

Example:

CALL ENTRYLAYER.API.CREATE_EMPTY_PROJECT('Manual Review', PARSE_JSON('{"description":"Built by Cortex"}'));

Signature:

CALL ENTRYLAYER.API.CREATE_PROJECT(<name>, <source_object>, <options>);

Parameters:

NameTypeDescription
nameVARCHARDisplay name for the new project.
source_objectVARCHARFully qualified Snowflake source object name in DB.SCHEMA.OBJECT form; metadata-only operations never sample rows.
optionsVARIANTProject creation options such as description, workflow flags, and source_type; initial layout is generated automatically.

Returns: VARIANT

Guidance:

Creates an EntryLayer project from a fully qualified, unquoted Snowflake object name such as DB.SCHEMA.TABLE.

The procedure always generates the initial layout, matching the UI behavior.

options:

{
"description": "Project description",
"workflow_enabled": false,
"auto_save_enabled": false,
"multi_step_enabled": false,
"source_type": "table"
}

Input contract: name VARCHAR, source_object VARCHAR = unquoted DB.SCHEMA.OBJECT, options VARIANT = CreateProjectOptions.

CreateProjectOptions contract:

{
"description": "string optional",
"workflow_enabled": false,
"auto_save_enabled": false,
"multi_step_enabled": false,
"source_type": "table | view | semantic_view"
}

Success data contract:

{
"project": Project,
"project_id": "proj_123",
"sync_config_id": 123,
"layout": {
"field_count": 2,
"section_count": 1,
"warnings": [
],
"fields_matched": 0,
"fields_created": 2
}
}

Guardrail: Automatic layout generation always runs. The procedure only reads source column metadata through restricted caller rights.

Idempotency: not idempotent. Each successful call creates a new project. Before retrying after an uncertain client timeout, call LIST_PROJECTS and inspect existing projects.

Example:

CALL ENTRYLAYER.API.CREATE_PROJECT('Invoice Exceptions', 'FINANCE_DB.BILLING.UNPAID_INVOICES', PARSE_JSON('{"description":"Review unpaid invoice exceptions"}'));

Signature:

CALL ENTRYLAYER.API.GET_PROJECT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Returns metadata for one EntryLayer project.

Parameters:

  • project_id: numeric id or proj_<numeric_id>, for example proj_5201.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project": Project
}

Project contract:

{
"project_id": "proj_123",
"internal_id": 123,
"name": "Name",
"description": "string or null",
"status": "active | archived",
"org_id": 1,
"source_object": "DB.SCHEMA.OBJECT or null",
"source_type": "table | view | semantic_view | null",
"workflow_enabled": false,
"auto_save_enabled": false,
"multi_step_enabled": false,
"created_at": "ISO-8601",
"updated_at": "ISO-8601"
}

Guardrail: Use GET_PROJECT for lightweight metadata. Use GET_PROJECT_LAYOUT only when field/layout metadata is needed.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_PROJECT('proj_5201');

Signature:

CALL ENTRYLAYER.API.GET_PROJECT_LAYOUT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Returns project metadata, published layout structure, and effective field definitions for one EntryLayer project.

Field definitions are resolved for API use: published layout values win, and registry values fill gaps.

This is metadata-only: it does not return source table rows, submission rows, or cell values.

Parameters:

  • project_id: numeric id or proj_<numeric_id>, for example proj_5201.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project": Project,
"layout": LayoutSummary,
"fields": [
EffectiveField
]
}

LayoutSummary contract:

{
"version_id": 123,
"version_number": 1,
"status": "published",
"published_at": "ISO-8601 or null",
"field_count": 2,
"section_count": 1,
"structure": {
...published form structure...
}
}

EffectiveField contract:

{
"field_id": 123,
"code": "COLUMN_NAME",
"title": "Display Label",
"field_type": "Text | Numeric | Date | Checkbox | Select | Label | Variant",
"required": false,
"description": "string or null",
"source": "snowflake | csv | null",
"config": {},
"values": [],
"field_group_id": null,
"parent_field_id": null
}

Guardrail: data.fields is the canonical parsed field list for automation. data.layout.structure is the raw published layout for UI shape.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_PROJECT_LAYOUT('proj_5201');

Signature:

CALL ENTRYLAYER.API.LIST_PROJECTS();

Returns: VARIANT

Guidance:

Returns EntryLayer projects visible to the admin SQL API surface. The options overload supports archived and child-project inspection.

Input contract: no-arg form, or options VARIANT = ProjectListOptions.

ProjectListOptions contract:

{
"include_archived": false,
"include_children": false,
"limit": 100
}

Success data contract:

{
"projects": [
Project
]
}

Guardrail: no-arg LIST_PROJECTS returns active top-level projects. Use include_archived only for admin review or restore workflows.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_PROJECTS();
CALL ENTRYLAYER.API.LIST_PROJECTS(PARSE_JSON('{"include_archived":true,"include_children":true,"limit":50}'));

Signature:

CALL ENTRYLAYER.API.LIST_PROJECTS(<options>);

Parameters:

NameTypeDescription
optionsVARIANTOptional filters such as include_archived, include_children, and limit.

Returns: VARIANT

Guidance:

Returns EntryLayer projects visible to the admin SQL API surface. The options overload supports archived and child-project inspection.

Input contract: no-arg form, or options VARIANT = ProjectListOptions.

ProjectListOptions contract:

{
"include_archived": false,
"include_children": false,
"limit": 100
}

Success data contract:

{
"projects": [
Project
]
}

Guardrail: no-arg LIST_PROJECTS returns active top-level projects. Use include_archived only for admin review or restore workflows.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_PROJECTS();
CALL ENTRYLAYER.API.LIST_PROJECTS(PARSE_JSON('{"include_archived":true,"include_children":true,"limit":50}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_PROJECT(<project_id>, <updates>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Updates project-level build settings.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>; updates VARIANT = ProjectUpdates.

ProjectUpdates contract:

{
"name": "string optional",
"description": "string optional",
"workflow_enabled": boolean,
"auto_save_enabled": boolean,
"multi_step_enabled": boolean,
"notify_on_submission": boolean,
"notify_on_review": boolean
}

Success data contract:

{
"project": Project
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects. Use RESTORE_PROJECT first.

Guardrail: This does not change source configuration, layout, workflow states, submissions, or access grants.

Idempotency: idempotent for the same updates; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_PROJECT('proj_123', PARSE_JSON('{"name":"Invoice Exceptions","auto_save_enabled":true}'));

Signature:

CALL ENTRYLAYER.API.ARCHIVE_PROJECT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Archives a project and blocks SQL API build mutations until restored.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project": Project,
"archived": true|false
}

Archived-project behavior: if already archived, returns success with archived=false and leaves state unchanged.

Guardrail: Archiving is a project lifecycle operation, not deletion. It does not export or remove source data.

Idempotency: idempotent and safe to retry.

Example:

CALL ENTRYLAYER.API.ARCHIVE_PROJECT('proj_123');

Signature:

CALL ENTRYLAYER.API.RESTORE_PROJECT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Restores an archived project so build mutations can resume.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project": Project,
"restored": true|false
}

Archived-project behavior: this is the only build SQL API mutation intentionally allowed for archived projects.

Guardrail: Restore does not run source syncs or create submissions.

Idempotency: idempotent and safe to retry.

Example:

CALL ENTRYLAYER.API.RESTORE_PROJECT('proj_123');

Signature:

CALL ENTRYLAYER.API.SET_PROJECT_FOLDER(<project_id>, <folder_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
folder_idVARCHAREntryLayer folder identifier.

Returns: VARIANT

Guidance:

Assigns a project to a folder, or clears the folder when folder_id is NULL or blank.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>; folder_id VARCHAR = positive folder id or NULL.

Success data contract:

{
"project": Project
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects. Use RESTORE_PROJECT first.

Guardrail: The folder must belong to the same EntryLayer organization.

Idempotency: idempotent for the same folder assignment; safe to retry.

Example:

CALL ENTRYLAYER.API.SET_PROJECT_FOLDER('proj_123', '10');

Signature:

CALL ENTRYLAYER.API.GET_PROJECT_DRAFT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Returns the current editable draft, creating one from the published layout if needed. Stable section_id and row_id values are backfilled for SQL automation.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project": Project,
"draft": FormVersion
}

FormVersion contract:

{
"version_id": 123,
"project_id": "proj_123",
"version_number": 2,
"status": "draft",
"structure": DraftStructure,
"created_at": "ISO-8601",
"updated_at": "ISO-8601",
"published_at": null,
"parent_version_id": 122,
"has_draft_changes": true
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Read the returned updated_at and pass it to SAVE_PROJECT_DRAFT options.expected_updated_at when replacing the whole draft.

Idempotency: read operation with lazy id backfill; safe to retry.

Example:

CALL ENTRYLAYER.API.GET_PROJECT_DRAFT('proj_123');

Signature:

CALL ENTRYLAYER.API.SAVE_PROJECT_DRAFT(<project_id>, <draft>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
draftVARIANTFull draft payload containing project form structure and settings; see FormVersion and DraftStructure.
optionsVARIANTDraft save options, including expected_updated_at for optimistic locking.

Returns: VARIANT

Guidance:

Replaces the editable draft structure. Use this for full-structure saves after composing DraftStructure client-side.

Input contract: project_id VARCHAR; draft VARIANT = DraftStructure or

{
"structure": DraftStructure
}

; options VARIANT = {“expected_updated_at”:“ISO-8601 optional”}.

Success data contract:

{
"draft": FormVersion
}

Archived-project behavior: returns ERR_FORBIDDEN for archived projects. Use RESTORE_PROJECT first.

Guardrail: This is a whole-draft replacement. Prefer targeted section, field, validation, and rule procedures when changing a small part of the form.

Validation guardrail: sections, rows, fields, available_fields, index_field_ids, form rules, configs, ids, and Select values are validated before persistence. Malformed nested objects return ERR_VALIDATION.

Idempotency: replacement mutation. Safe retry only when using options.expected_updated_at or after verifying current draft state.

Example:

CALL ENTRYLAYER.API.SAVE_PROJECT_DRAFT('proj_123', PARSE_JSON('{"sections":[],"available_fields":[],"rules":[]}'), PARSE_JSON('{"expected_updated_at":"2026-05-26T16:00:00Z"}'));

Signature:

CALL ENTRYLAYER.API.PUBLISH_PROJECT_DRAFT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Publishes the current draft so users see the form design changes.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"version": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND or ERR_FORBIDDEN for archived projects.

Guardrail: Section, field, validation, and rule edits affect the draft only until this procedure succeeds.

Idempotency: not idempotent after a successful publish because the draft is promoted. Retry only after GET_PROJECT_DRAFT confirms a draft still exists.

Example:

CALL ENTRYLAYER.API.PUBLISH_PROJECT_DRAFT('proj_123');

Signature:

CALL ENTRYLAYER.API.DISCARD_PROJECT_DRAFT(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Deletes the current draft and leaves the published form unchanged.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project_id": "proj_123",
"discarded": true|false
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This loses unpublished draft edits. GET_PROJECT_LAYOUT remains the published user-facing form.

Idempotency: idempotent; discarded=false means there was no active draft.

Example:

CALL ENTRYLAYER.API.DISCARD_PROJECT_DRAFT('proj_123');

Signature:

CALL ENTRYLAYER.API.LIST_PROJECT_VERSIONS(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Lists draft, published, and archived form versions for a project.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project_id": "proj_123",
"versions": [
FormVersion
]
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Use version_id from this response with REVERT_PROJECT_VERSION.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_PROJECT_VERSIONS('proj_123');

Signature:

CALL ENTRYLAYER.API.REVERT_PROJECT_VERSION(<project_id>, <version_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
version_idVARCHARPublished form version identifier to inspect or revert to.

Returns: VARIANT

Guidance:

Creates a new draft copied from an earlier form version. Publish separately after inspection.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>; version_id VARCHAR = numeric form version id.

Success data contract:

{
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Revert does not publish automatically. Review with GET_PROJECT_DRAFT before PUBLISH_PROJECT_DRAFT.

Idempotency: not idempotent. Each successful call creates/replaces a draft from the selected version.

Example:

CALL ENTRYLAYER.API.REVERT_PROJECT_VERSION('proj_123', '42');

Signature:

CALL ENTRYLAYER.API.CREATE_SECTION(<project_id>, <section>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
sectionVARIANTSection definition to create; see Section.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Creates a section in the editable draft.

Input contract: project_id VARCHAR; section VARIANT = SectionCreate; placement VARIANT = Placement.

SectionCreate contract:

{
"title": "Section title",
"section_id": "sec_... optional",
"relationship_id": 123 optional,
"rows": [
Row
] optional
}

Success data contract:

{
"section": Section,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Section edits affect the draft only. Publish before expecting users to see the section.

Idempotency: not idempotent unless the caller supplies and de-duplicates a section_id externally.

Example:

CALL ENTRYLAYER.API.CREATE_SECTION('proj_123', PARSE_JSON('{"title":"Review"}'), PARSE_JSON('{"index":0}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_SECTION(<project_id>, <section_id>, <updates>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
section_idVARCHARStable form section identifier from the draft/layout payload.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Updates draft section metadata.

Input contract: project_id VARCHAR; section_id VARCHAR = stable section_id; updates VARIANT =

{
"title": "string optional",
"relationship_id": 123 optional
}

Success data contract:

{
"section": Section,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: rows are not replaced by UPDATE_SECTION. Use field/section procedures or SAVE_PROJECT_DRAFT for full-structure edits.

Idempotency: idempotent for the same updates; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_SECTION('proj_123', 'sec_abc', PARSE_JSON('{"title":"Review Details"}'));

Signature:

CALL ENTRYLAYER.API.REMOVE_SECTION(<project_id>, <section_id>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
section_idVARCHARStable form section identifier from the draft/layout payload.
optionsVARIANTRemoval behavior options, such as whether contained fields should be archived or moved.

Returns: VARIANT

Guidance:

Removes a draft section. By default its fields move to available_fields; options.archive_fields=true archives manual fields instead.

Input contract: project_id VARCHAR; section_id VARCHAR; options VARIANT =

{
"archive_fields": false
}

Success data contract:

{
"section": Section,
"moved_to_available": [
field_id
],
"archived_fields": [
field_id
],
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Do not archive source-backed fields. Use default move-to-available behavior when unsure.

Idempotency: not idempotent after removal. Retry only after checking GET_PROJECT_DRAFT.

Example:

CALL ENTRYLAYER.API.REMOVE_SECTION('proj_123', 'sec_abc', PARSE_JSON('{"archive_fields":false}'));

Signature:

CALL ENTRYLAYER.API.MOVE_SECTION(<project_id>, <section_id>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
section_idVARCHARStable form section identifier from the draft/layout payload.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Moves a draft section to a new index.

Input contract: project_id VARCHAR; section_id VARCHAR; placement VARIANT =

{
"index": 0
}

Success data contract:

{
"section": Section,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Draft-only until PUBLISH_PROJECT_DRAFT succeeds.

Idempotency: idempotent only when the section is already at the requested index.

Example:

CALL ENTRYLAYER.API.MOVE_SECTION('proj_123', 'sec_abc', PARSE_JSON('{"index":0}'));

Signature:

CALL ENTRYLAYER.API.CREATE_ROW(<project_id>, <row_payload>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
row_payloadVARIANTRow definition to create; see Row.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Creates a row in a draft section. Rows are layout containers for fields.

Input contract: project_id VARCHAR; row VARIANT =

{
"row_id": "row_... optional",
"fields": [
Field
] optional
}

; placement VARIANT = Placement with section_id or section_index.

Success data contract:

{
"row": Row,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Prefer MOVE_FIELD for ordinary field placement. Use CREATE_ROW when Cortex needs explicit row boundaries.

Validation guardrail: row.fields must be an array of Field objects. Nested field configs, ids, types, and Select values are validated before persistence.

Idempotency: not idempotent unless the caller supplies and de-duplicates row_id externally.

Example:

CALL ENTRYLAYER.API.CREATE_ROW('proj_123', PARSE_JSON('{"fields":[]}'), PARSE_JSON('{"section_id":"sec_abc","row_index":0}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_ROW(<project_id>, <row_id>, <updates>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
row_idVARCHARStable layout row identifier from the draft/layout payload.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Replaces the field array for a draft row.

Input contract: project_id VARCHAR; row_id VARCHAR; updates VARIANT =

{
"fields": [
Field
]
}

Success data contract:

{
"row": Row,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This is a structural operation. Use MOVE_FIELD for safer single-field moves.

Validation guardrail: updates.fields must be an array of Field objects. Nested field configs, ids, types, and Select values are validated before persistence.

Idempotency: idempotent for the same fields array; safe to retry after reading GET_PROJECT_DRAFT.

Example:

CALL ENTRYLAYER.API.UPDATE_ROW('proj_123', 'row_abc', PARSE_JSON('{"fields":[]}'));

Signature:

CALL ENTRYLAYER.API.REMOVE_ROW(<project_id>, <row_id>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
row_idVARCHARStable layout row identifier from the draft/layout payload.
optionsVARIANTRemoval behavior options for the row and its contained fields.

Returns: VARIANT

Guidance:

Removes a row from the draft. By default its fields move to available_fields; options.archive_fields=true archives fields instead.

Input contract: project_id VARCHAR; row_id VARCHAR; options VARIANT =

{
"archive_fields": false
}

Success data contract:

{
"row": Row,
"moved_to_available": [
field_id
],
"archived_fields": [
field_id
],
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Move-to-available is safer than archive when the row contains source-backed fields.

Idempotency: not idempotent after removal. Retry only after checking GET_PROJECT_DRAFT.

Example:

CALL ENTRYLAYER.API.REMOVE_ROW('proj_123', 'row_abc', PARSE_JSON('{"archive_fields":false}'));

Signature:

CALL ENTRYLAYER.API.MOVE_ROW(<project_id>, <row_id>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
row_idVARCHARStable layout row identifier from the draft/layout payload.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Moves a draft row to another section or index.

Input contract: project_id VARCHAR; row_id VARCHAR; placement VARIANT =

{
"section_id": "sec_abc",
"row_index": 0
}

Success data contract:

{
"row": Row,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Draft-only until publish. Use stable row_id values from GET_PROJECT_DRAFT.

Idempotency: idempotent only when the row is already in the requested location.

Example:

CALL ENTRYLAYER.API.MOVE_ROW('proj_123', 'row_abc', PARSE_JSON('{"section_id":"sec_abc","row_index":0}'));

Signature:

CALL ENTRYLAYER.API.CREATE_FIELD(<project_id>, <field>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
fieldVARIANTField definition to create; see Field.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Creates a manual field, allocates a stable field_id, and places it in the editable draft.

Input contract: project_id VARCHAR; field VARIANT = FieldCreate; placement VARIANT = Placement.

FieldCreate contract:

{
"title": "Label",
"field_type": "Text | Numeric | Date | Checkbox | Select | Label | Variant",
"required": false,
"description": "optional",
"code": "optional",
"config": {},
"values": []
}

Select values contract: values may be

[
"Open",
"Closed"
]

or [{“title”:“Open”,“value”:“O”}]; SQL API normalizes them to objects with title and value.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Field registry ids are never reused. Store the returned field_id for validation, rule, move, and publish steps.

Idempotency: not idempotent. Each successful call creates a new field_id.

Example:

CALL ENTRYLAYER.API.CREATE_FIELD('proj_123', PARSE_JSON('{"title":"Reviewer Comment","field_type":"Text","config":{"multiline":true}}'), PARSE_JSON('{"section_id":"sec_abc"}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_FIELD(<project_id>, <field_id>, <updates>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Updates draft field metadata while preserving the stable field_id.

Input contract: project_id VARCHAR; field_id VARCHAR = numeric field id or stable field code; updates VARIANT = partial Field excluding field_id and source.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: field_type cannot be changed after creation. Create a new field and archive the old one when the type needs to change.

Idempotency: idempotent for the same updates; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_FIELD('proj_123', 'AMOUNT', PARSE_JSON('{"title":"Approved Amount","config":{"format":"currency"}}'));

Signature:

CALL ENTRYLAYER.API.ARCHIVE_FIELD(<project_id>, <field_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.

Returns: VARIANT

Guidance:

Archives a manual field and removes it from the draft structure.

Input contract: project_id VARCHAR; field_id VARCHAR = numeric field id or stable field code.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Source-backed fields are protected and return ERR_FORBIDDEN. Use MOVE_FIELD to remove a field from the visible layout without archiving.

Idempotency: not idempotent after archive. Retry only after checking GET_PROJECT_DRAFT and field registry state.

Example:

CALL ENTRYLAYER.API.ARCHIVE_FIELD('proj_123', 'AMOUNT');

Signature:

CALL ENTRYLAYER.API.MOVE_FIELD(<project_id>, <field_id>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Moves a draft field to a section row position or to available_fields.

Input contract: project_id VARCHAR; field_id VARCHAR = numeric field id or stable field code; placement VARIANT = Placement.

Placement contract:

{
"section_id": "sec_... optional",
"row_id": "row_... optional",
"section_index": 0 optional,
"row_index": 0 optional,
"field_index": 0 optional,
"available": false optional
}

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Use stable section_id and row_id values from GET_PROJECT_DRAFT instead of deriving layout position from titles.

Idempotency: idempotent only when moving the same field to the same stable placement after confirming the draft state.

Example:

CALL ENTRYLAYER.API.MOVE_FIELD('proj_123', 'AMOUNT', PARSE_JSON('{"section_id":"sec_abc","field_index":0}'));

Signature:

CALL ENTRYLAYER.API.SET_FIELD_VALIDATION(<project_id>, <field_id>, <validation>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
validationVARIANTField validation metadata such as required, range, format, defaults, and select values; see FieldValidation.

Returns: VARIANT

Guidance:

Merges validation and type-specific config into a draft field.

Input contract: project_id VARCHAR; field_id VARCHAR = numeric field id or stable field code; validation VARIANT = FieldValidation.

FieldValidation contract:

{
"required": true,
"range_min": 0,
"range_max": 100,
"round_precision": 2,
"format": "currency | percentage | plain",
"include_time": false,
"allow_multiple": false,
"default_value": "optional",
"read_only": false,
"values": [],
"lookup": {},
"parent_field_id": null,
"primary_key": false
}

Select values contract: values may be

[
"Open",
"Closed"
]

or [{“title”:“Open”,“value”:“O”}]; SQL API normalizes them to objects with title and value.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Validation changes affect the draft only. Publish before users see the rule.

Idempotency: idempotent for the same validation values; safe to retry.

Example:

CALL ENTRYLAYER.API.SET_FIELD_VALIDATION('proj_123', 'AMOUNT', PARSE_JSON('{"required":true,"range_min":0,"format":"currency"}'));

Signature:

CALL ENTRYLAYER.API.CLEAR_FIELD_VALIDATION(<project_id>, <field_id>, <keys>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
keysVARIANTArray of validation keys to clear, or an empty array to clear all supported validation keys.

Returns: VARIANT

Guidance:

Clears selected validation/config keys from a draft field.

Input contract: project_id VARCHAR; field_id VARCHAR = numeric field id or stable field code; keys VARIANT =

[
"required",
"range_min",
"range_max",
"values",
...
]

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: required resets to false, values resets to an empty array, parent_field_id resets to null, and config keys are removed.

Idempotency: idempotent for the same keys; safe to retry.

Example:

CALL ENTRYLAYER.API.CLEAR_FIELD_VALIDATION('proj_123', 'AMOUNT', PARSE_JSON('["required","range_min"]'));

Signature:

CALL ENTRYLAYER.API.SET_PRIMARY_KEYS(<project_id>, <field_ids>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idsVARIANTArray of field identifiers to mark as the project primary key fields.

Returns: VARIANT

Guidance:

Marks the supplied fields as primary keys in form metadata and clears primary_key from all other fields.

Input contract: project_id VARCHAR; field_ids VARIANT =

[
numeric field id or stable field code
]

Success data contract:

{
"project_id": "proj_123",
"field_ids": [
123
],
"updated_version_ids": [
version_id
]
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Primary key metadata is used for source-backed identity and read-only display. Prefer stable field codes when Cortex is composing calls from GET_PROJECT_LAYOUT output.

Idempotency: idempotent for the same field id list; safe to retry.

Example:

CALL ENTRYLAYER.API.SET_PRIMARY_KEYS('proj_123', PARSE_JSON('["ORDER_ID"]'));

Signature:

CALL ENTRYLAYER.API.EXTRACT_VARIANT_FIELDS(<project_id>, <field_id>, <paths>, <placement>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
pathsVARIANTVariant paths or field paths to expose as generated fields.
placementVARIANTPlacement object describing where the section, row, or field should be inserted or moved; see Placement.

Returns: VARIANT

Guidance:

Creates formula-backed scalar fields from caller-supplied JSON paths on a Variant field.

Input contract: project_id VARCHAR; field_id VARCHAR = Variant source field numeric id or stable field code; paths VARIANT =

[
{
"path": "customer.name",
"title": "Customer Name",
"field_type": "Text"
}
]

; placement VARIANT = Placement or {“available”:true}.

Success data contract:

{
"source_field_id": 123,
"fields": [
Field
],
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This procedure does not discover paths by sampling source rows. Cortex must supply paths from metadata, customer input, or a previously approved schema.

Idempotency: not idempotent. Each successful call creates new field ids.

Example:

CALL ENTRYLAYER.API.EXTRACT_VARIANT_FIELDS('proj_123', 'PAYLOAD', PARSE_JSON('[{"path":"customer.name","title":"Customer Name","field_type":"Text"}]'), PARSE_JSON('{"available":true}'));

Signature:

CALL ENTRYLAYER.API.LIST_FORM_RULES(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Lists form logic rules from the editable draft.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"rules": [
FormRule
]
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Rules in the draft are not user-facing until PUBLISH_PROJECT_DRAFT succeeds.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_FORM_RULES('proj_123');

Signature:

CALL ENTRYLAYER.API.GENERATE_FORM_RULE(<project_id>, <prompt>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
promptVARCHARNatural-language rule request sent to Cortex; use field names/titles only, not sensitive data.

Returns: VARIANT

Guidance:

Generates a proposed form-rule expression from natural language using the current draft fields.

Input contract: project_id VARCHAR; prompt VARCHAR = natural-language rule request.

Success data contract:

{
"rule": {
"expression": "{Reviewer Comment}.required = {Status}.value == \"Open\"",
"target_field_id": 123,
"target_property": "required",
"enabled": true,
"validation_error": null optional
}
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This invokes Cortex with the caller prompt plus field titles/types only. EntryLayer does not add source rows, submission values, source samples, select option values, or field descriptions to the prompt.

Guardrail: This does not save the rule. Inspect rule.validation_error, then call CREATE_FORM_RULE with the returned rule when valid.

Prompt safety: do not include PII, source row values, submission values, or secrets in the prompt.

Idempotency: read-like generation. Repeated calls may produce equivalent but not byte-identical expressions.

Example:

CALL ENTRYLAYER.API.GENERATE_FORM_RULE('proj_123', 'Require Reviewer Comment when Status is Open');

Signature:

CALL ENTRYLAYER.API.CREATE_FORM_RULE(<project_id>, <rule>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
ruleVARIANTForm rule definition; see FormRule.

Returns: VARIANT

Guidance:

Creates a form logic rule in the editable draft.

Input contract: project_id VARCHAR; rule VARIANT = FormRule without id or with caller-supplied unique id.

FormRule contract:

{
"id": "rule_... optional",
"expression": "{Reviewer Comment}.required = {Status}.value == \"Open\"",
"target_field_id": 123,
"target_property": "visible | enabled | required",
"description": "optional",
"enabled": true
}

Success data contract:

{
"rule": FormRule,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Rule expressions are validated against draft field titles. The left-hand field title should match target_field_id and target_property.

Idempotency: not idempotent unless the caller supplies and de-duplicates rule.id.

Example:

CALL ENTRYLAYER.API.CREATE_FORM_RULE('proj_123', PARSE_JSON('{"expression":"{Reviewer Comment}.required = {Status}.value == \"Open\"","target_field_id":123,"target_property":"required","enabled":true}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_FORM_RULE(<project_id>, <rule_id>, <updates>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
rule_idVARCHARForm rule identifier returned by LIST_FORM_RULES or CREATE_FORM_RULE.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Updates a form logic rule in the editable draft.

Input contract: project_id VARCHAR; rule_id VARCHAR; updates VARIANT = partial FormRule.

Success data contract:

{
"rule": FormRule,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Updating expression, target_field_id, or target_property re-runs rule validation against draft fields.

Idempotency: idempotent for the same updates; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_FORM_RULE('proj_123', 'rule_abc', PARSE_JSON('{"description":"Updated rule"}'));

Signature:

CALL ENTRYLAYER.API.SET_FORM_RULE_ENABLED(<project_id>, <rule_id>, <enabled>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
rule_idVARCHARForm rule identifier returned by LIST_FORM_RULES or CREATE_FORM_RULE.
enabledBOOLEANWhether the form rule should be active.

Returns: VARIANT

Guidance:

Enables or disables a form logic rule in the editable draft.

Input contract: project_id VARCHAR; rule_id VARCHAR; enabled BOOLEAN.

Success data contract:

{
"rule": FormRule,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Disabled rules remain in draft JSON for later re-enable; publish before users see the enabled state change.

Idempotency: idempotent for the same enabled value; safe to retry.

Example:

CALL ENTRYLAYER.API.SET_FORM_RULE_ENABLED('proj_123', 'rule_abc', FALSE);

Signature:

CALL ENTRYLAYER.API.DELETE_FORM_RULE(<project_id>, <rule_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
rule_idVARCHARForm rule identifier returned by LIST_FORM_RULES or CREATE_FORM_RULE.

Returns: VARIANT

Guidance:

Removes a form logic rule from the editable draft.

Input contract: project_id VARCHAR; rule_id VARCHAR.

Success data contract:

{
"rule_id": "rule_abc",
"deleted": true|false,
"draft": FormVersion
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: deleted=false means the rule was not present; publish before users see rule removal.

Idempotency: idempotent; safe to retry.

Example:

CALL ENTRYLAYER.API.DELETE_FORM_RULE('proj_123', 'rule_abc');

Signature:

CALL ENTRYLAYER.API.GET_WORKFLOW(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Returns workflow configuration for one active project.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"workflow": Workflow
}

Workflow contract:

{
"states": [
WorkflowState
],
"within_category_modes": {
},
"allow_send_back": true,
"allow_reopen": true
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Workflow metadata controls review state movement only. It does not create, update, delete, or export submissions.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_WORKFLOW('proj_123');

Signature:

CALL ENTRYLAYER.API.UPDATE_WORKFLOW(<project_id>, <workflow>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
workflowVARIANTWorkflow configuration payload; see Workflow.

Returns: VARIANT

Guidance:

Replaces project workflow states and workflow-level settings.

Input contract: project_id VARCHAR; workflow VARIANT = Workflow.

WorkflowState contract:

{
"id": 123 optional,
"label": "Submitted",
"category": "editable | in_review | approved | rejected",
"order_in_category": 0,
"color": "#94a3b8",
"is_exit_point": false,
"exit_target_state_ids": [
123
] optional,
"back_edge_target_state_ids": [
122
] optional,
"acl_entries": [
] optional,
"is_locked_down": false
}

Success data contract:

{
"workflow": Workflow
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Replacing a workflow can invalidate assumptions in customer automation. Read GET_WORKFLOW first and preserve states you do not intend to change.

Idempotency: replacement mutation. Retry only after checking GET_WORKFLOW or when sending the same known-good workflow payload.

Example:

CALL ENTRYLAYER.API.UPDATE_WORKFLOW('proj_123', PARSE_JSON('{"states":[{"label":"Draft","category":"editable","order_in_category":0}],"within_category_modes":{},"allow_send_back":true,"allow_reopen":true}'));

Signature:

CALL ENTRYLAYER.API.LIST_WORKFLOW_TEMPLATES();

Returns: VARIANT

Guidance:

Lists workflow templates that can be applied to projects.

Input contract: none.

Success data contract:

{
"templates": [
{
"template_id": 123,
"scope": "builtin | org | project",
"org_id": 1,
"source_project_id": null,
"name": "Template name",
"description": "string or null"
}
]
}

Archived-project behavior: not applicable.

Guardrail: Listing templates does not modify project workflow state.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_WORKFLOW_TEMPLATES();

Signature:

CALL ENTRYLAYER.API.APPLY_WORKFLOW_TEMPLATE(<project_id>, <template_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
template_idVARCHARWorkflow template identifier returned by LIST_WORKFLOW_TEMPLATES.

Returns: VARIANT

Guidance:

Applies a workflow template to an active project.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>; template_id VARCHAR = numeric workflow template id.

Success data contract:

{
"workflow": Workflow
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: The backend may reject template application when existing submissions make the workflow change unsafe.

Idempotency: replacement mutation. Not safe to blindly retry after a timeout; call GET_WORKFLOW first.

Example:

CALL ENTRYLAYER.API.APPLY_WORKFLOW_TEMPLATE('proj_123', '1');

Signature:

CALL ENTRYLAYER.API.CLONE_WORKFLOW(<project_id>, <source_project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
source_project_idVARCHARProject id to copy workflow settings from.

Returns: VARIANT

Guidance:

Copies workflow configuration from one active project to another active project in the same organization.

Input contract: project_id VARCHAR = target project; source_project_id VARCHAR = source project.

Success data contract:

{
"workflow": Workflow
}

Archived-project behavior: returns ERR_NOT_FOUND when either project is archived.

Guardrail: Clone copies workflow configuration only. It does not copy layout, fields, relationships, submissions, or access grants.

Idempotency: replacement mutation. Retry only after checking GET_WORKFLOW on the target project.

Example:

CALL ENTRYLAYER.API.CLONE_WORKFLOW('proj_456', 'proj_123');

Signature:

CALL ENTRYLAYER.API.LIST_RELATIONSHIPS(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Lists parent-child project relationships for an active project.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project_id": "proj_123",
"relationships": [
Relationship
]
}

Relationship contract:

{
"id": 1,
"parent_project_id": 123,
"child_project_id": 456,
"parent_field_id": 10,
"child_field_id": 11,
"label": "Line Items",
"sort_order": 0,
"parent_project_title": "Invoices",
"child_project_title": "Invoice Lines",
"is_system_managed": false
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Relationship metadata only. No child records or source rows are returned.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_RELATIONSHIPS('proj_123');

Signature:

CALL ENTRYLAYER.API.CREATE_RELATIONSHIP(<project_id>, <relationship>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
relationshipVARIANTRelationship definition between projects or source-backed fields; see Relationship.

Returns: VARIANT

Guidance:

Creates a parent-child relationship from project_id to relationship.child_project_id.

Input contract: project_id VARCHAR = parent project; relationship VARIANT = RelationshipCreate.

RelationshipCreate contract:

{
"child_project_id": "proj_456",
"parent_field_id": 10 optional,
"child_field_id": 11 optional,
"label": "Line Items" optional
}

Success data contract:

{
"relationship": Relationship
}

Archived-project behavior: returns ERR_NOT_FOUND for archived parent or child projects.

Guardrail: Parent and child must be different active projects in the same organization; circular relationships are rejected.

Idempotency: not idempotent. Check LIST_RELATIONSHIPS before retrying after an uncertain timeout.

Example:

CALL ENTRYLAYER.API.CREATE_RELATIONSHIP('proj_123', PARSE_JSON('{"child_project_id":"proj_456","label":"Line Items"}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_RELATIONSHIP(<relationship_id>, <updates>);

Parameters:

NameTypeDescription
relationship_idVARCHARProject relationship identifier returned by LIST_RELATIONSHIPS or CREATE_RELATIONSHIP.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Updates relationship label, join fields, or sort order.

Input contract: relationship_id VARCHAR = positive numeric id; updates VARIANT =

{
"label": "string optional",
"parent_field_id": 10 optional,
"child_field_id": 11 optional,
"sort_order": 0 optional
}

Success data contract:

{
"relationship": Relationship
}

Archived-project behavior: archived relationships return ERR_NOT_FOUND.

Guardrail: child_project_id cannot be changed. Delete and recreate the relationship if the child project is wrong.

Idempotency: idempotent for the same updates; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_RELATIONSHIP('1', PARSE_JSON('{"label":"Invoice Lines","sort_order":1}'));

Signature:

CALL ENTRYLAYER.API.DELETE_RELATIONSHIP(<relationship_id>);

Parameters:

NameTypeDescription
relationship_idVARCHARProject relationship identifier returned by LIST_RELATIONSHIPS or CREATE_RELATIONSHIP.

Returns: VARIANT

Guidance:

Archives a parent-child project relationship.

Input contract: relationship_id VARCHAR = positive numeric id.

Success data contract:

{
"relationship": Relationship
}

Archived-project behavior: already archived relationships return ERR_NOT_FOUND.

Guardrail: This removes relationship metadata only. It does not delete projects, fields, submissions, or source data.

Idempotency: not idempotent after successful archive. Retry only after checking LIST_RELATIONSHIPS.

Example:

CALL ENTRYLAYER.API.DELETE_RELATIONSHIP('1');

Signature:

CALL ENTRYLAYER.API.LIST_FOLDERS();

Returns: VARIANT

Guidance:

Lists project folders for the EntryLayer organization.

Input contract: none.

Success data contract:

{
"folders": [
Folder
]
}

Folder contract:

{
"id": 1,
"name": "Finance",
"project_count": 3,
"created_at": "ISO-8601",
"updated_at": "ISO-8601"
}

Archived-project behavior: not applicable.

Guardrail: Folder list contains app organization metadata only.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_FOLDERS();

Signature:

CALL ENTRYLAYER.API.CREATE_FOLDER(<name>);

Parameters:

NameTypeDescription
nameVARCHARDisplay name for the new folder.

Returns: VARIANT

Guidance:

Creates a project folder.

Input contract: name VARCHAR = non-empty folder name.

Success data contract:

{
"folder": Folder
}

Archived-project behavior: not applicable.

Guardrail: Folder names must be valid for the current organization and may conflict with existing folders.

Idempotency: not idempotent when duplicate names are allowed by the backend; check LIST_FOLDERS before retrying.

Example:

CALL ENTRYLAYER.API.CREATE_FOLDER('Finance');

Signature:

CALL ENTRYLAYER.API.UPDATE_FOLDER(<folder_id>, <updates>);

Parameters:

NameTypeDescription
folder_idVARCHAREntryLayer folder identifier.
updatesVARIANTPartial update object; supported keys depend on the target object and are documented in Guidance.

Returns: VARIANT

Guidance:

Renames a project folder.

Input contract: folder_id VARCHAR = positive numeric id; updates VARIANT =

{
"name": "New folder name"
}

Success data contract:

{
"folder": Folder
}

Archived-project behavior: not applicable.

Guardrail: The only supported update key is name.

Idempotency: idempotent for the same name; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_FOLDER('1', PARSE_JSON('{"name":"Finance Ops"}'));

Signature:

CALL ENTRYLAYER.API.DELETE_FOLDER(<folder_id>);

Parameters:

NameTypeDescription
folder_idVARCHAREntryLayer folder identifier.

Returns: VARIANT

Guidance:

Deletes a project folder and unassigns projects from that folder.

Input contract: folder_id VARCHAR = positive numeric id.

Success data contract:

{
"folder_id": 1,
"deleted": true
}

Archived-project behavior: not applicable.

Guardrail: Projects are not archived or deleted. Their folder assignment is cleared.

Idempotency: not idempotent after delete; missing folders return ERR_NOT_FOUND.

Example:

CALL ENTRYLAYER.API.DELETE_FOLDER('1');

Signature:

CALL ENTRYLAYER.API.GRANT_ACCESS(<project_id>, <role_name>, <access_level>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
role_nameVARCHARSnowflake role name to grant or revoke project access for.
access_levelVARCHARProject access level to grant: viewer, user, or admin.

Returns: VARIANT

Guidance:

Grants a Snowflake role access to an EntryLayer project.

Parameters:

  • project_id: numeric id or proj_<numeric_id>.
  • role_name: unquoted Snowflake role identifier.
  • access_level: viewer, user, or admin.

Input contract: project_id VARCHAR, role_name VARCHAR = unquoted Snowflake role identifier, access_level VARCHAR = viewer | user | admin.

Success data contract:

{
"project_id": "proj_123",
"role_name": "ROLE_NAME",
"access_level": "viewer | user | admin",
"grant_id": 123
}

Guardrail: This manages EntryLayer project access for Snowflake roles only. It does not grant Snowflake object privileges.

Idempotency: upsert-style for the same project and role. Repeating the same level is safe; changing access_level updates the existing role grant.

Example:

CALL ENTRYLAYER.API.GRANT_ACCESS('proj_5201', 'FINANCE_TEAM_ROLE', 'user');

Signature:

CALL ENTRYLAYER.API.REVOKE_ACCESS(<project_id>, <role_name>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
role_nameVARCHARSnowflake role name to grant or revoke project access for.

Returns: VARIANT

Guidance:

Removes a Snowflake role access grant from an EntryLayer project. The operation is idempotent if the role does not currently have a grant.

Parameters:

  • project_id: numeric id or proj_<numeric_id>.
  • role_name: unquoted Snowflake role identifier.

Input contract: project_id VARCHAR, role_name VARCHAR = unquoted Snowflake role identifier.

Success data contract:

{
"project_id": "proj_123",
"role_name": "ROLE_NAME",
"revoked": true
}

Guardrail: The operation is idempotent. revoked=false means there was no active grant to remove.

Example:

CALL ENTRYLAYER.API.REVOKE_ACCESS('proj_5201', 'FINANCE_TEAM_ROLE');

Signature:

CALL ENTRYLAYER.API.LIST_ACCESS(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Lists role and user grants for an EntryLayer project, including field-group read/edit scopes.

Parameters:

  • project_id: numeric id or proj_<numeric_id>.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project_id": "proj_123",
"access": [
AccessGrant
]
}

AccessGrant contract:

{
"grant_id": 123,
"project_id": "proj_123",
"subject_type": "role | user",
"subject_identifier": "ROLE_NAME or USERNAME",
"subject_label": "display label",
"account_id": null,
"account_snowflake_username": null,
"role_name": "ROLE_NAME",
"access_level": "viewer | user | admin",
"can_submit": false,
"can_read": true,
"can_edit": false,
"can_delete": false,
"can_manage": false,
"field_groups": [
FieldGroupPermission
]
}

Guardrail: Admin seat does not imply project can_read. Use LIST_ACCESS to verify explicit user/role grants and field-group scopes before querying grid or submission procedures.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_ACCESS('proj_5201');

Signature:

CALL ENTRYLAYER.API.UPSERT_ACCESS(<project_id>, <subject_type>, <subject_identifier>, <permissions>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
subject_typeVARCHARAccess subject type, typically role for Snowflake role-based grants.
subject_identifierVARCHARIdentifier for the access subject, such as a Snowflake role name.
permissionsVARIANTPermission object to set for the subject; see AccessPermissions.

Returns: VARIANT

Guidance:

Creates or updates a project access grant for a role or user.

Input contract: project_id VARCHAR; subject_type VARCHAR = role | user; subject_identifier VARCHAR = role name, Snowflake username, or email; permissions VARIANT = AccessPermissions.

AccessPermissions contract:

{
"can_read": true,
"can_submit": false,
"can_edit": false,
"can_delete": false,
"can_manage": false
}

Success data contract:

{
"access": AccessGrant,
"operation": "created | updated"
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This manages EntryLayer project permissions only. It does not grant Snowflake object privileges.

Idempotency: upsert-style for the same project and subject; safe to retry.

Example:

CALL ENTRYLAYER.API.UPSERT_ACCESS('proj_123', 'role', 'FINANCE_TEAM_ROLE', PARSE_JSON('{"can_read":true,"can_submit":true,"can_edit":true}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_ACCESS(<project_id>, <grant_id>, <permissions>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
grant_idVARCHARAccess grant identifier returned by LIST_ACCESS or UPSERT_ACCESS.
permissionsVARIANTPermission object to replace or update for this grant; see AccessPermissions.

Returns: VARIANT

Guidance:

Updates an existing project access grant by grant id.

Input contract: project_id VARCHAR; grant_id VARCHAR = positive numeric id; permissions VARIANT = partial AccessPermissions.

Success data contract:

{
"access": AccessGrant
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Use LIST_ACCESS or APP_PUBLIC.PROJECT_ACCESS to find grant_id. Unknown permission keys return ERR_INVALID_INPUT.

Idempotency: idempotent for the same permissions; safe to retry.

Example:

CALL ENTRYLAYER.API.UPDATE_ACCESS('proj_123', '12', PARSE_JSON('{"can_manage":true}'));

Signature:

CALL ENTRYLAYER.API.DELETE_ACCESS(<project_id>, <grant_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
grant_idVARCHARAccess grant identifier returned by LIST_ACCESS or UPSERT_ACCESS.

Returns: VARIANT

Guidance:

Deletes an existing project access grant by grant id.

Input contract: project_id VARCHAR; grant_id VARCHAR = positive numeric id.

Success data contract:

{
"project_id": "proj_123",
"grant_id": 12,
"deleted": true
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This deletes EntryLayer project access only. It does not revoke Snowflake roles or object privileges.

Idempotency: not idempotent after delete; missing grants return ERR_NOT_FOUND.

Example:

CALL ENTRYLAYER.API.DELETE_ACCESS('proj_123', '12');

Signature:

CALL ENTRYLAYER.API.GET_PROJECT_ANALYTICS(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Returns aggregate project status counts and recent submission counts for admin inspection.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project_id": "proj_123",
"analytics": {
"status_counts": [
{
"state_id": 1,
"count": 2
}
],
"total": 2,
"submissions_over_time": [
{
"date": "YYYY-MM-DD",
"count": 1
}
],
"recent_created": 1,
"recent_updated": 1
}
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Aggregate counts only. No submission field values or source row data are returned.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_PROJECT_ANALYTICS('proj_123');

Signature:

CALL ENTRYLAYER.API.LIST_PROJECT_ACCESS_LOG(<project_id>, <filters>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
filtersVARIANTFilter object for list results; see the command guidance for supported keys.

Returns: VARIANT

Guidance:

Lists project access log rows for troubleshooting who viewed or changed project records.

Input contract: project_id VARCHAR; filters VARIANT =

{
"action": "string optional",
"account_id": 123 optional,
"skip": 0,
"limit": 50
}

Success data contract:

{
"project_id": "proj_123",
"items": [
{
"id": 1,
"submission_id": null,
"account_id": 42,
"action": "view",
"details": "string or null",
"created_at": "ISO-8601"
}
],
"total": 1
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Audit metadata only. This response uses account ids instead of emails and does not include submission payloads.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_PROJECT_ACCESS_LOG('proj_123', PARSE_JSON('{"limit":50}'));

Signature:

CALL ENTRYLAYER.API.LIST_PROJECT_CHANGELOG(<project_id>, <filters>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
filtersVARIANTFilter object for list results; see the command guidance for supported keys.

Returns: VARIANT

Guidance:

Lists form-structure changelog rows created during publish.

Input contract: project_id VARCHAR; filters VARIANT =

{
"entity_type": "field optional",
"changed_by": 42 optional,
"skip": 0,
"limit": 50
}

Success data contract:

{
"project_id": "proj_123",
"items": [
{
"id": 1,
"project_id": "proj_123",
"action": "rename_field",
"entity_type": "field",
"entity_name": "Amount",
"old_value": "Old",
"new_value": "New",
"changed_by": 42,
"created_at": "ISO-8601"
}
],
"total": 1
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Changelog captures form design metadata, not row values. This response uses account ids instead of emails.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_PROJECT_CHANGELOG('proj_123', PARSE_JSON('{"limit":50}'));

Signature:

CALL ENTRYLAYER.API.GET_SOURCE_CONFIG(<project_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.

Returns: VARIANT

Guidance:

Returns source sync configuration metadata for an active project.

Input contract: project_id VARCHAR = numeric id or proj_<numeric_id>.

Success data contract:

{
"project_id": "proj_123",
"source_configs": [
SourceConfig
]
}

SourceConfig contract:

{
"sync_config_id": 123,
"project_id": "proj_123",
"direction": "import",
"source_object": "DB.SCHEMA.TABLE",
"source_type": "table | view | semantic_view",
"enabled": true,
"column_mappings": [
{
"snowflake_column": "COL",
"field_id": 10
}
],
"last_sync_at": "ISO-8601 or null",
"last_sync_status": "string or null",
"last_sync_message": "string or null",
"created_at": "ISO-8601",
"updated_at": "ISO-8601"
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: Metadata only. No source rows, submission rows, or sync execution results are returned.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_SOURCE_CONFIG('proj_123');

Signature:

CALL ENTRYLAYER.API.RECONFIGURE_SOURCE(<project_id>, <source_object>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
source_objectVARCHARFully qualified Snowflake source object name in DB.SCHEMA.OBJECT form; metadata-only operations never sample rows.
optionsVARIANTSource reconfiguration options, including source_type and metadata handling; no source rows are sampled.

Returns: VARIANT

Guidance:

Validates a new source object, regenerates the layout, publishes it, and updates import source configuration without running a source sync.

Input contract: project_id VARCHAR; source_object VARCHAR = unquoted DB.SCHEMA.OBJECT; options VARIANT =

{
"source_type": "table | view | semantic_view"
}

Success data contract:

{
"project_id": "proj_123",
"source_config": SourceConfig,
"layout": {
"version_id": 123,
"version_number": 2,
"field_count": 3,
"section_count": 1,
"warnings": [
],
"fields_matched": 1,
"fields_created": 2
}
}

Archived-project behavior: returns ERR_NOT_FOUND for archived projects.

Guardrail: This reads source column metadata through restricted caller rights, does not sample rows, does not run sync, and does not create/update/delete submissions.

Idempotency: replacement mutation. Not safe to blindly retry after a timeout; call GET_SOURCE_CONFIG and GET_PROJECT_LAYOUT first.

Example:

CALL ENTRYLAYER.API.RECONFIGURE_SOURCE('proj_123', 'FINANCE_DB.BILLING.UNPAID_INVOICES', PARSE_JSON('{"source_type":"table"}'));

Assign or update a user’s seat type.

Signature:

CALL ENTRYLAYER.API.SET_USER_SEAT(<username>, <seat_type>);

Parameters:

NameTypeDescription
usernameVARCHARSnowflake username to update in EntryLayer seat management.
seat_typeVARCHARSeat tier to assign, such as view, act, build, or admin.

Returns: VARIANT

Guidance:

Creates or updates an EntryLayer user membership for the current app organization and assigns a seat type.

Input contract: username VARCHAR = unquoted Snowflake username identifier; seat_type VARCHAR = view | act | build | admin.

Success data contract:

{
"username": "JSMITH",
"seat_type": "build",
"organization_id": 1,
"account_id": 123,
"member_id": 456
}

Guardrail: This changes EntryLayer app membership only. It does not grant Snowflake roles, source object privileges, or project access.

Validation guardrail: username cannot be blank and must match an unquoted Snowflake identifier.

Billing guardrail: seat changes may affect anonymous paid-seat billing. Billing events must never include usernames, emails, table names, project names, row keys, or row values.

Idempotency: idempotent for the same username and seat_type; safe to retry.

Example:

CALL ENTRYLAYER.API.SET_USER_SEAT('JSMITH', 'build');

Downgrade a user to the view seat.

Signature:

CALL ENTRYLAYER.API.REVOKE_USER_SEAT(<username>);

Parameters:

NameTypeDescription
usernameVARCHARSnowflake username to update in EntryLayer seat management.

Returns: VARIANT

Guidance:

Downgrades a user to the free view seat.

Input contract: username VARCHAR = unquoted Snowflake username identifier.

Success data contract:

{
"username": "JSMITH",
"seat_type": "view",
"organization_id": 1,
"account_id": 123,
"member_id": 456
}

Guardrail: This does not remove the Snowflake user, revoke Snowflake roles, or remove project access grants. Review LIST_ACCESS/PROJECT_ACCESS separately when offboarding.

Validation guardrail: username cannot be blank and must match an unquoted Snowflake identifier.

Idempotency: idempotent for users already on the view seat; safe to retry.

Example:

CALL ENTRYLAYER.API.REVOKE_USER_SEAT('JSMITH');

Archive duplicate seat rows for the same Snowflake username inside an org.

Signature:

CALL ENTRYLAYER.API.REPAIR_USER_SEATS(<org_id>);

Parameters:

NameTypeDescription
org_idNUMBERInternal EntryLayer organization id to repair.

Returns: VARIANT

Guidance:

Archives duplicate organization membership rows for the same Snowflake username, keeping the highest-priority active seat row.

Input contract: org_id NUMBER = EntryLayer organization id from SET_USER_SEAT output or admin diagnostics.

Success data contract:

{
"organization_id": 1,
"archived_count": 0
}

Guardrail: Use only for seat-state repair. It does not merge accounts, project access grants, submissions, or audit history.

Idempotency: idempotent after duplicates are repaired; safe to retry.

Example:

CALL ENTRYLAYER.API.REPAIR_USER_SEATS(1);

List users and their seat types.

Signature:

CALL ENTRYLAYER.API.LIST_USERS();

Returns: VARIANT

Guidance:

Lists active EntryLayer users and their seat types for the current app organization.

Input contract: none.

Success data contract:

{
"users": [
UserSeat
]
}

UserSeat contract:

{
"username": "JSMITH",
"seat_type": "view | act | build | admin"
}

Guardrail: Admin-only membership inspection. Do not use this as a Snowflake role or object privilege audit.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_USERS();

Admin-only billing observability. These procedures expose anonymous aggregate billing state only: no usernames, emails, source object names, row keys, row values, or query text.

Signature:

CALL ENTRYLAYER.API.LIST_BILLING_LEDGER();

Returns: VARIANT

Guidance:

Lists anonymous monthly seat-billing ledger rows recorded by EntryLayer.

Input contract: none.

Success data contract:

{
"rows": [
BillingLedgerRow
]
}

BillingLedgerRow contract:

{
"billing_month": "YYYY-MM",
"event_class": "ACT_SEAT_MONTHLY | BUILD_ADMIN_SEAT_MONTHLY",
"observed_count": 0,
"billed_count": 0,
"seat_days": 0,
"days_in_month": 30,
"calculated_amount_cents": 0,
"emitted_amount_cents": 0,
"status": "pending | emitted | failed",
"emitted_at": "ISO-8601 or null",
"last_error": "string or null",
"calculation_version": "string"
}

Guardrail: Billing ledger output is aggregate and anonymous. It is for marketplace billing reconciliation, not user activity auditing.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_BILLING_LEDGER();

Signature:

CALL ENTRYLAYER.API.PREVIEW_BILLING();

Returns: VARIANT

Guidance:

Returns anonymous current-month paid-seat billing counts and estimated full-month amounts.

Input contract: none.

Success data contract:

{
"rows": [
BillingPreviewRow
]
}

BillingPreviewRow contract:

{
"billing_month": "YYYY-MM",
"event_class": "ACT_SEAT_MONTHLY | BUILD_ADMIN_SEAT_MONTHLY",
"active_seat_count": 0,
"monthly_unit_price_cents": 2400,
"estimated_full_month_cents": 0,
"snapshot_date": "YYYY-MM-DD",
"note": "string"
}

Guardrail: Preview rows are aggregate and anonymous. They must not include usernames, emails, project names, source objects, row keys, row values, or query text.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.PREVIEW_BILLING();

Manually suspend the app to save credits.

Signature:

CALL ENTRYLAYER.API.SUSPEND_APP();

Returns: VARIANT

Guidance:

Suspends the EntryLayer SPCS service and compute pool to save credits.

Input contract: none.

Success data contract:

{
"service": "core.entrylayer_service",
"compute_pool": "entrylayer_pool"
}

Guardrail: Operational recovery command only. It does not change app data, projects, source grants, or submissions.

Idempotency: idempotent where Snowflake ALTER SERVICE/COMPUTE POOL suspend is idempotent; safe to retry when confirming shutdown.

Example:

CALL ENTRYLAYER.API.SUSPEND_APP();

Resume the app after it has been suspended. This also repairs installs where Snowflake granted manifest v2 privileges but did not invoke the callback.

Signature:

CALL ENTRYLAYER.API.RESUME_APP();

Returns: VARIANT

Guidance:

Resumes or repairs the EntryLayer SPCS service and compute pool after suspension or missing grant-callback provisioning.

Input contract: none.

Success data contract:

{
"service": "core.entrylayer_service",
"compute_pool": "entrylayer_pool"
}

Guardrail: Operational recovery command only. It provisions app-owned compute resources declared in the manifest and does not request external access or source row data.

Idempotency: idempotent where Snowflake ALTER SERVICE/COMPUTE POOL resume is idempotent; safe to retry during recovery.

Example:

CALL ENTRYLAYER.API.RESUME_APP();

API.EXTRACT_PROJECT_SUBMISSIONS(project_id)

Section titled “API.EXTRACT_PROJECT_SUBMISSIONS(project_id)”

Signature:

SELECT * FROM TABLE(ENTRYLAYER.API.EXTRACT_PROJECT_SUBMISSIONS(<project_id>));

Parameters:

NameTypeDescription
project_idNUMBERNumeric EntryLayer project id used by table functions and extract SQL helpers.

Returns: TABLE ( submission_id NUMBER, project_id NUMBER, project_title VARCHAR, status VARCHAR, created_at TIMESTAMP_NTZ, updated_at TIMESTAMP_NTZ, snowflake_row_key VARCHAR, field_values VARIANT )

Guidance:

Admin-only table function that returns approved project submission rows from app-owned tables for downstream customer SQL.

Input contract: project_id NUMBER = internal numeric project id; include_foreign_keys BOOLEAN = include hidden/system relationship keys needed for joins.

Return table contract: submission_id NUMBER, project_id NUMBER, project_title VARCHAR, status VARCHAR, created_at TIMESTAMP_NTZ, updated_at TIMESTAMP_NTZ, snowflake_row_key VARCHAR, field_values VARIANT.

Guardrail: Only published-form fields allowed by the extract metadata are included. Masked stored values are emitted as JSON null. This function does not write customer tables.

Idempotency: read-only and safe to retry.

Example:

SELECT * FROM TABLE(ENTRYLAYER.API.EXTRACT_PROJECT_SUBMISSIONS(123, FALSE));

API.EXTRACT_PROJECT_SUBMISSIONS(project_id, include_foreign_keys)

Section titled “API.EXTRACT_PROJECT_SUBMISSIONS(project_id, include_foreign_keys)”

Signature:

SELECT * FROM TABLE(ENTRYLAYER.API.EXTRACT_PROJECT_SUBMISSIONS(<project_id>, <include_foreign_keys>));

Parameters:

NameTypeDescription
project_idNUMBERNumeric EntryLayer project id used by table functions and extract SQL helpers.
include_foreign_keysBOOLEANWhen true, include configured relationship/foreign-key fields in the extracted rows.

Returns: TABLE ( submission_id NUMBER, project_id NUMBER, project_title VARCHAR, status VARCHAR, created_at TIMESTAMP_NTZ, updated_at TIMESTAMP_NTZ, snowflake_row_key VARCHAR, field_values VARIANT )

Guidance:

Admin-only table function that returns approved project submission rows from app-owned tables for downstream customer SQL.

Input contract: project_id NUMBER = internal numeric project id; include_foreign_keys BOOLEAN = include hidden/system relationship keys needed for joins.

Return table contract: submission_id NUMBER, project_id NUMBER, project_title VARCHAR, status VARCHAR, created_at TIMESTAMP_NTZ, updated_at TIMESTAMP_NTZ, snowflake_row_key VARCHAR, field_values VARIANT.

Guardrail: Only published-form fields allowed by the extract metadata are included. Masked stored values are emitted as JSON null. This function does not write customer tables.

Idempotency: read-only and safe to retry.

Example:

SELECT * FROM TABLE(ENTRYLAYER.API.EXTRACT_PROJECT_SUBMISSIONS(123, FALSE));

Signature:

SELECT * FROM TABLE(ENTRYLAYER.API.EXTRACT_PROJECT_FIELD_METADATA(<project_id>, <include_foreign_keys>));

Parameters:

NameTypeDescription
project_idNUMBERNumeric EntryLayer project id used by table functions and extract SQL helpers.
include_foreign_keysBOOLEANWhen true, include relationship/foreign-key field metadata.

Returns: TABLE ( project_id NUMBER, project_title VARCHAR, field_id NUMBER, field_key VARCHAR, field_code VARCHAR, field_title VARCHAR, field_type VARCHAR, source VARCHAR, field_order NUMBER, is_hidden BOOLEAN, is_system_managed BOOLEAN, relationship_id NUMBER, relationship_role VARCHAR, related_project_id NUMBER, related_project_title VARCHAR, include_in_extract_sql BOOLEAN, projection_sql VARCHAR )

Guidance:

Admin-only table function that describes extractable published fields and generated projection SQL fragments for a project.

Input contract: project_id NUMBER = internal numeric project id; include_foreign_keys BOOLEAN = include hidden/system relationship keys needed for joins.

Return table contract: project_id, project_title, field_id, field_key, field_code, field_title, field_type, source, field_order, is_hidden, is_system_managed, relationship_id, relationship_role, related_project_id, related_project_title, include_in_extract_sql, projection_sql.

Guardrail: Metadata only. Use this to inspect extract shape or build SELECT clauses; it does not expose source row samples or mutate submissions.

Idempotency: read-only and safe to retry.

Example:

SELECT * FROM TABLE(ENTRYLAYER.API.EXTRACT_PROJECT_FIELD_METADATA(123, FALSE));

Signature:

SELECT ENTRYLAYER.API.GET_PROJECT_EXTRACT_SQL(<project_id>, <include_foreign_keys>);

Parameters:

NameTypeDescription
project_idNUMBERNumeric EntryLayer project id used by table functions and extract SQL helpers.
include_foreign_keysBOOLEANWhen true, generate extract SQL that includes relationship/foreign-key fields.

Returns: VARCHAR

Guidance:

Returns a generated SELECT statement that calls API.EXTRACT_PROJECT_SUBMISSIONS and projects field_values into columns.

Input contract: project_id NUMBER = internal numeric project id; include_foreign_keys BOOLEAN = include hidden/system relationship keys needed for joins.

Return contract: VARCHAR containing SQL text. This scalar function does not use the VARIANT envelope.

Guardrail: Review generated SQL before running it, especially when field titles contain spaces or special characters. Replace ENTRYLAYER if your installed app name differs.

Idempotency: read-only and safe to retry.

Example:

SELECT ENTRYLAYER.API.GET_PROJECT_EXTRACT_SQL(123, FALSE);

Signature:

CALL ENTRYLAYER.API.GET_WORKFLOW_TEMPLATE(<template_id>);

Parameters:

NameTypeDescription
template_idVARCHARWorkflow template identifier returned by LIST_WORKFLOW_TEMPLATES.

Returns: VARIANT

Guidance:

Returns one workflow template and its state/config payload so Cortex can inspect it before applying.

Input contract: template_id VARCHAR = numeric workflow template id from LIST_WORKFLOW_TEMPLATES.

Success data contract:

{
"template": {
"template_id": 123,
"scope": "builtin | org",
"name": "Template",
"description": "string",
"config": Workflow
}
}

Guardrail: read-only. Does not mutate project workflow state.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_WORKFLOW_TEMPLATE('1');

Signature:

CALL ENTRYLAYER.API.PREVIEW_WORKFLOW_TEMPLATE(<project_id>, <template>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
templateVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Validates a workflow template payload and previews replacement effects without saving changes.

Input contract: project_id VARCHAR; template VARIANT = Workflow or

{
"config": Workflow
}

Success data contract:

{
"project": Project,
"preview": {
"state_count": 3,
"dropped_state_ids": [
1
],
"within_category_modes": {
},
"allow_send_back": true,
"allow_reopen": true,
"warnings": [
]
}
}

Guardrail: preview only. Call APPLY_WORKFLOW_TEMPLATE, CLONE_WORKFLOW, or UPDATE_WORKFLOW to save.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.PREVIEW_WORKFLOW_TEMPLATE('proj_123', PARSE_JSON('{"states":[{"label":"Draft","category":"editable","order_in_category":0}],"within_category_modes":{}}'));

Signature:

CALL ENTRYLAYER.API.LIST_WORKFLOW_TEMPLATE_PROJECTS();

Returns: VARIANT

Guidance:

Lists active workflow-enabled projects available for the UI-style “from a project” picker.

Input contract: none.

Success data contract:

{
"projects": [
{
"project_id": "proj_123",
"name": "Orders",
"workflow": Workflow
}
]
}

Guardrail: read-only. Does not copy workflow settings.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_WORKFLOW_TEMPLATE_PROJECTS();

Signature:

CALL ENTRYLAYER.API.LIST_FIELD_DISTINCT_VALUES(<project_id>, <field_id>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Loads distinct source values for a mapped field to help configure Select dropdown options.

Input contract: field_id may be numeric id or field code; options =

{
"limit": 100
}

Success data contract:

{
"project_id": "proj_123",
"field_id": 10,
"source_column": "STATUS",
"values": [
"Open",
"Closed"
]
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus explicit project can_read because this returns source data values.

Guardrail: the procedure first asks the service for a permission-checked query plan, then a private restricted-caller-rights helper runs a narrow SELECT DISTINCT for one mapped column. It does not sample broad rows or fall back to app-context source reads.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_FIELD_DISTINCT_VALUES('proj_123', 'STATUS', PARSE_JSON('{"limit":100}'));

Signature:

CALL ENTRYLAYER.API.SET_FIELD_LOOKUP(<project_id>, <field_id>, <lookup>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
lookupVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Sets lookup configuration on a draft field.

Input contract: lookup =

{
"project_id": "proj_456",
"key_field_id": "10",
"display_field_id": "11",
"filter_field_id": "12" optional,
"filter_value": "Active" optional
}

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Guardrail: draft mutation only. Publish required before users see changes.

Idempotency: replacement mutation for lookup config.

Example:

CALL ENTRYLAYER.API.SET_FIELD_LOOKUP('proj_123', 'CUSTOMER', PARSE_JSON('{"project_id":"proj_456","key_field_id":"ID","display_field_id":"NAME"}'));

Signature:

CALL ENTRYLAYER.API.CLEAR_FIELD_LOOKUP(<project_id>, <field_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.

Returns: VARIANT

Guidance:

Removes lookup configuration from a draft field.

Input contract: field_id may be numeric id or field code.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Guardrail: draft mutation only. Publish required before users see changes.

Idempotency: idempotent; clearing an absent lookup leaves the field unchanged.

Example:

CALL ENTRYLAYER.API.CLEAR_FIELD_LOOKUP('proj_123', 'CUSTOMER');

Signature:

CALL ENTRYLAYER.API.SET_FIELD_CASCADE(<project_id>, <field_id>, <parent_field_id>, <field_values>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
parent_field_idVARCHARSee command guidance for expected value.
field_valuesVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Sets Select child options and their parent option mappings.

Input contract: field_values =

[
{
"title": "Open",
"value": "Open",
"parent_value_ids": [
"North"
]
}
]

. field_id and parent_field_id must both reference Select fields.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Guardrail: draft mutation only. Publish required before users see changes.

Idempotency: replacement mutation for the cascade values.

Example:

CALL ENTRYLAYER.API.SET_FIELD_CASCADE('proj_123', 'CITY', 'STATE', PARSE_JSON('[{"title":"Austin","value":"Austin","parent_value_ids":["TX"]}]'));

Signature:

CALL ENTRYLAYER.API.SET_FIELD_GROUP(<project_id>, <field_id>, <field_group_id>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
field_idVARCHARStable form field identifier from the draft/layout payload.
field_group_idVARCHARSee command guidance for expected value.

Returns: VARIANT

Guidance:

Assigns or clears a field_group_id on a draft field.

Input contract: field_group_id VARCHAR = numeric id, NULL, empty string, or “none” to clear.

Success data contract:

{
"field": Field,
"draft": FormVersion
}

Guardrail: field groups affect field visibility/editability after publish and access configuration.

Idempotency: replacement mutation.

Example:

CALL ENTRYLAYER.API.SET_FIELD_GROUP('proj_123', 'AMOUNT', '3');

Signature:

CALL ENTRYLAYER.API.SET_ACCESS_FIELD_GROUPS(<project_id>, <grant_id>, <field_groups>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
grant_idVARCHARAccess grant identifier returned by LIST_ACCESS or UPSERT_ACCESS.
field_groupsVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Replaces field-group read/edit permissions for an access grant.

Input contract: field_groups =

[
{
"field_group_id": 3,
"permission": "read | edit"
}
]

Success data contract:

{
"project_id": "proj_123",
"grant_id": 12,
"field_groups": [
{
"field_group_id": 3,
"permission": "read"
}
]
}

Guardrail: this affects field-level data access. Verify with GET_SUBMISSION or the UI after saving.

Idempotency: replacement mutation; safe to retry with the same full field_groups array.

Example:

CALL ENTRYLAYER.API.SET_ACCESS_FIELD_GROUPS('proj_123', '12', PARSE_JSON('[{"field_group_id":3,"permission":"edit"}]'));

Signature:

CALL ENTRYLAYER.API.QUERY_SUBMISSION_GRID(<project_id>, <query>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
queryVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Queries source-backed and materialized grid rows using the same project permission gate as the UI.

Input contract: query =

{
"startRow": 0,
"endRow": 100,
"sortModel": [],
"filterModel": {},
"requestedColumns": [
10
],
"search": null,
"editedOnly": false,
"archivedOnly": false,
"statusFilter": "all"
}

Success data contract:

{
"grid": {
"rows": [
SubmissionGridRow
],
"lastRow": 100,
"nextStartRow": 100,
"warning": null
}
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus explicit project can_read. Admin seat alone is not enough.

Guardrail: no APP_PUBLIC view exposes submission values; use this procedure only with explicit customer approval. Source-backed grid reads fail closed with ERR_CALLER_CONTEXT_REQUIRED when caller source-row context is unavailable.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.QUERY_SUBMISSION_GRID('proj_123', PARSE_JSON('{"startRow":0,"endRow":100}'));

Signature:

CALL ENTRYLAYER.API.QUERY_RELATIONSHIP_SUBMISSION_GRID(<relationship_id>, <query>);

Parameters:

NameTypeDescription
relationship_idVARCHARProject relationship identifier returned by LIST_RELATIONSHIPS or CREATE_RELATIONSHIP.
queryVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Queries child rows for a relationship using the same grid contract as QUERY_SUBMISSION_GRID.

Input contract: relationship_id VARCHAR; query = SubmissionGridQuery with optional parentJoinValue.

Success data contract:

{
"grid": {
"rows": [
SubmissionGridRow
],
"lastRow": 100,
"nextStartRow": 100,
"warning": null
}
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus parent project can_read.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.QUERY_RELATIONSHIP_SUBMISSION_GRID('1', PARSE_JSON('{"startRow":0,"endRow":100,"parentJoinValue":"ORD-100"}'));

Signature:

CALL ENTRYLAYER.API.GET_SUBMISSION(<submission_id>, <options>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Returns full materialized submission detail, field values, structure, permissions, workflow states, relationships, and breadcrumb.

Input contract: options =

{
"use_draft": false
}

Success data contract:

{
"submission": SubmissionDetail
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_read.

Guardrail: field-group hidden/read/edit flags are applied like the UI. Source-backed materialized submissions fail closed with ERR_CALLER_CONTEXT_REQUIRED when caller source-row context is unavailable.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_SUBMISSION('100', PARSE_JSON('{"use_draft":false}'));

Signature:

CALL ENTRYLAYER.API.GET_VIRTUAL_SUBMISSION(<project_id>, <sync_config_id>, <row_key>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
sync_config_idVARCHARSee command guidance for expected value.
row_keyVARCHARSee command guidance for expected value.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Returns one source-backed virtual submission detail without materializing it.

Input contract: project_id VARCHAR; sync_config_id VARCHAR; row_key VARCHAR; options =

{
"use_draft": false
}

Success data contract:

{
"submission": SubmissionDetail
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_read and caller-governed source row access.

Guardrail: source row access follows Snowflake caller governance; no submission values are exposed through views. Fails closed with ERR_CALLER_CONTEXT_REQUIRED when caller source-row context is unavailable.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_VIRTUAL_SUBMISSION('proj_123', '5', 'row-key', PARSE_JSON('{}'));

Signature:

CALL ENTRYLAYER.API.LIST_SUBMISSION_STATUS_HISTORY(<submission_id>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.

Returns: VARIANT

Guidance:

Lists workflow transition history for one submission.

Input contract: submission_id VARCHAR = numeric id.

Success data contract:

{
"history": [
SubmissionStatusHistory
]
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_read. Audit details may be redacted based on permissions.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.LIST_SUBMISSION_STATUS_HISTORY('100');

Signature:

CALL ENTRYLAYER.API.GET_SUBMISSION_BREADCRUMB(<submission_id>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.

Returns: VARIANT

Guidance:

Returns parent breadcrumb entries for a materialized submission.

Input contract: submission_id VARCHAR = numeric id.

Success data contract:

{
"breadcrumb": [
BreadcrumbEntry
]
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_read.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_SUBMISSION_BREADCRUMB('100');

Signature:

CALL ENTRYLAYER.API.GET_VIRTUAL_SUBMISSION_BREADCRUMB(<project_id>, <sync_config_id>, <row_key>, <field_values>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
sync_config_idVARCHARSee command guidance for expected value.
row_keyVARCHARSee command guidance for expected value.
field_valuesVARIANTSee command guidance for expected value.

Returns: VARIANT

Guidance:

Returns breadcrumb entries for a virtual source-backed row.

Input contract: field_values =

{
"Field Title": "display value"
}

and is used only for breadcrumb labels.

Success data contract:

{
"breadcrumb": [
BreadcrumbEntry
]
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_read.

Guardrail: keep field_values minimal; do not include secrets or unnecessary source data.

Idempotency: read-only and safe to retry.

Example:

CALL ENTRYLAYER.API.GET_VIRTUAL_SUBMISSION_BREADCRUMB('proj_123', '5', 'row-key', PARSE_JSON('{"Order Key":"100"}'));

Signature:

CALL ENTRYLAYER.API.CREATE_SUBMISSION(<project_id>, <fields>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
fieldsVARIANTSee command guidance for expected value.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Creates a manual/materialized submission and optionally writes initial field values atomically.

Input contract: fields =

[
{
"field_id": 10 or "code": "STATUS",
"value": "Open",
"expected_value": "optional"
}
]

. Values must be strings/scalars/null; arrays of scalar select labels are serialized safely.

Success data contract:

{
"submission": SubmissionRead
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_submit. Admin seat alone is not enough.

Guardrail: all fields validate before commit. Unknown, read-only, hidden, masked, invalid select/date/number, or workflow-locked fields fail with ERR_VALIDATION/ERR_FORBIDDEN.

Idempotency: non-idempotent; retry may create another submission. Verify with QUERY_SUBMISSION_GRID before retrying after an unknown timeout.

Example:

CALL ENTRYLAYER.API.CREATE_SUBMISSION('proj_123', PARSE_JSON('[{"code":"STATUS","value":"Open"}]'), PARSE_JSON('{}'));

Signature:

CALL ENTRYLAYER.API.MATERIALIZE_VIRTUAL_SUBMISSION(<project_id>, <sync_config_id>, <row_key>, <options>);

Parameters:

NameTypeDescription
project_idVARCHAREntryLayer project identifier; SQL API procedures accept proj_<id> or the numeric id as text.
sync_config_idVARCHARSee command guidance for expected value.
row_keyVARCHARSee command guidance for expected value.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Materializes a source-backed virtual row into an EntryLayer submission.

Input contract: project_id VARCHAR; sync_config_id VARCHAR; row_key VARCHAR; options reserved.

Success data contract:

{
"submission": SubmissionRead
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus can_edit/materialize access and caller-governed source row access.

Guardrail: no source rows are stored until materialization succeeds. Masked source fields remain protected. Fails closed with ERR_CALLER_CONTEXT_REQUIRED when caller source-row context is unavailable.

Idempotency: idempotent for the same active sync_config_id + row_key when an active materialized submission already exists.

Example:

CALL ENTRYLAYER.API.MATERIALIZE_VIRTUAL_SUBMISSION('proj_123', '5', 'row-key', PARSE_JSON('{}'));

Signature:

CALL ENTRYLAYER.API.UPDATE_SUBMISSION_FIELDS(<submission_id>, <fields>, <options>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.
fieldsVARIANTSee command guidance for expected value.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Updates submission field values through the same validation, field-group, masking, and workflow guards as the UI.

Input contract: fields =

[
{
"field_id": 10 or "code": "STATUS",
"value": "Closed",
"expected_value": "Open" optional
}
]

Success data contract:

{
"fields": [
SubmissionField
]
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_edit; field groups must grant edit where configured.

Guardrail: read-only, hidden, masked, invalid select/date/number, and workflow-locked fields fail before persistence. Source-backed materialized submissions also require caller source-row context. Use expected_value for optimistic locking.

Idempotency: idempotent when setting the same values; expected_value makes retries conflict-safe.

Example:

CALL ENTRYLAYER.API.UPDATE_SUBMISSION_FIELDS('100', PARSE_JSON('[{"code":"STATUS","value":"Closed","expected_value":"Open"}]'), PARSE_JSON('{}'));

Signature:

CALL ENTRYLAYER.API.TRANSITION_SUBMISSION(<submission_id>, <target_state_id>, <comment>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.
target_state_idVARCHARSee command guidance for expected value.
commentVARCHARSee command guidance for expected value.

Returns: VARIANT

Guidance:

Moves a submission to a target workflow state.

Input contract: target_state_id VARCHAR = numeric workflow state id; comment VARCHAR optional.

Success data contract:

{
"submission": SubmissionRead
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_edit and workflow state ACL access.

Guardrail: invalid workflow transitions are rejected; comments should not include secrets or unnecessary PII.

Idempotency: non-idempotent because history entries are created. Verify current state before retrying.

Example:

CALL ENTRYLAYER.API.TRANSITION_SUBMISSION('100', '4', 'Verified against PO');

Signature:

CALL ENTRYLAYER.API.ARCHIVE_SUBMISSION(<submission_id>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.

Returns: VARIANT

Guidance:

Archives one submission after can_delete checks.

Input contract: submission_id VARCHAR = numeric id.

Success data contract:

{
"submission": SubmissionRead
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_delete.

Guardrail: archived submissions are read-only until restored.

Idempotency: mostly idempotent by outcome; an already archived submission may return not found.

Example:

CALL ENTRYLAYER.API.ARCHIVE_SUBMISSION('100');

Signature:

CALL ENTRYLAYER.API.RESTORE_SUBMISSION(<submission_id>);

Parameters:

NameTypeDescription
submission_idVARCHARSee command guidance for expected value.

Returns: VARIANT

Guidance:

Restores one archived submission after can_delete checks.

Input contract: submission_id VARCHAR = numeric id.

Success data contract:

{
"submission": SubmissionRead
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus project can_delete.

Guardrail: restore does not bypass workflow locks or field permissions for later edits.

Idempotency: idempotent by outcome.

Example:

CALL ENTRYLAYER.API.RESTORE_SUBMISSION('100');

Signature:

CALL ENTRYLAYER.API.CREATE_CHILD_SUBMISSION(<relationship_id>, <parent_value>, <fields>, <options>);

Parameters:

NameTypeDescription
relationship_idVARCHARProject relationship identifier returned by LIST_RELATIONSHIPS or CREATE_RELATIONSHIP.
parent_valueVARCHARSee command guidance for expected value.
fieldsVARIANTSee command guidance for expected value.
optionsVARIANTOptional JSON settings for the command; see Guidance for supported keys.

Returns: VARIANT

Guidance:

Creates a child submission through a relationship and pre-populates the child join field.

Input contract: fields uses the same contract as CREATE_SUBMISSION. parent_value is the parent join-key value.

Success data contract:

{
"submission": SubmissionRead
}

Permission contract: caller must have ENTRYLAYER_ADMIN plus parent project can_read and child project can_submit.

Guardrail: parent row must exist and be accessible. Initial fields validate before final commit.

Idempotency: non-idempotent; retry may create another child submission.

Example:

CALL ENTRYLAYER.API.CREATE_CHILD_SUBMISSION('1', 'ORD-100', PARSE_JSON('[{"code":"COMMENT","value":"Line note"}]'), PARSE_JSON('{}'));