Templates — API Reference
Package: dodil.data.pipeline.v1 · Service: PipelineService
Templates are a control-plane surface, and they are org-scoped, not bucket-scoped. There is no ListTemplates RPC on the Tables service and no /:bucket/tables/_templates route — the four per-pillar ListTemplates RPCs that used to exist were collapsed into one, with a facet filter selecting what each of them used to hardcode.
| RPC | HTTP |
|---|---|
PipelineService.ListTemplates | GET https://api.data.dodil.io/admin/templates |
PipelineService.GetTemplate | GET https://api.data.dodil.io/admin/templates/{template_id} |
Source: dodil-k3/bin/api/src/http/api/mod.rs:222-227, dodil-k3/proto/proto-k3/k3_pipeline.proto:129-138.
The facet filter
facet=table is what makes this the warehouse view: it pins the label filter warehouse_compatible=true on the Scriptum catalog. Each facet keeps the exact filter its retired per-pillar RPC used (dodil-k3/bin/api/src/services/pipeline/templates.rs:40-52):
?facet= | Server-side filter |
|---|---|
vector | category=embedding |
table | label warehouse_compatible=true |
object | label pillar=objects |
graph | label pillar=graph — no such templates published yet |
| (omitted) | the whole catalog |
Anything else is INVALID_ARGUMENT: “unknown facet ’…’ — expected one of vector, table, object, graph”. A caller-supplied category cannot relax a facet’s pinned one — the facet wins.
GetTemplate deliberately does not enforce a facet; any template id resolves.
ListTemplates
Request
dodil data
# Warehouse-compatible templates — the facet is pinned to TABLE by this command
dodil data table templates
# Free-text search / label filter
dodil data table templates --search ocr
dodil data table templates --label modality=pdf
# The whole catalog, with a category filter (a different command)
dodil data template list --category analysis
dodil data template get entity_pii_extractiondodil data table templates takes only --search and --label. --category lives on dodil data template list. Source: cli-shell/cli-k3/cmd/table_pipeline.go:103-150, cmd/template.go:98-102.
Response
message Template {
string id = 1; // Scriptum template id
string name = 2;
string description = 3;
repeated string tags = 4;
repeated string tools_required = 5;
map<string, string> labels = 6;
string category = 7; // e.g. "embedding" | "extraction"
// Typed I/O contract, proxied verbatim from Scriptum's GetTemplate.
dodil.data.common.v1.ScriptContract contract = 8;
repeated string modalities = 9; // ["text", "pdf", "image"]
// Accepted inputs, from the contract — these drive an ingest rule's globs
// and the "files matching X will be ingested" banner.
repeated string accepted_extensions = 10;
repeated string accepted_content_types = 11;
// Object-facet templates only: "markdown" | "text" | "json" | "file".
string output_kind = 12;
}{
"templates": [
{
"id": "entity_pii_extraction",
"name": "Entity & PII Extraction",
"description": "Extract structured entities and detect PII from any document.",
"tags": ["analysis", "pii"],
"labels": { "category": "analysis", "warehouse_compatible": "true" },
"category": "analysis",
"modalities": ["text", "pdf"],
"acceptedExtensions": ["pdf", "txt", "docx"],
"acceptedContentTypes": ["application/pdf", "text/plain"]
}
]
}There is no output_columns field on Template — earlier drafts of this page described one and then explained why it was always empty. The typed I/O contract lives on contract (a ScriptContract); a warehouse table’s actual column layout materialises lazily, on the template’s first ingest.
What’s in the warehouse-compatible catalog
The catalog is served by Scriptum, not by K3 — K3 proxies it and applies the facet filter. It changes independently of this documentation, so the authoritative list is the call itself:
dodil data table templatesCommonly used table-facet ids include classification, document_triage, entity_pii_extraction, ocr_extraction, summarization, sentiment_intent_analysis, translation, audio_transcription, code_intelligence, image_understanding, object_detection, video_surveillance, product_catalog_enrichment and review_analysis — but treat that as a sample, not an inventory. dodil data template get <id> returns the typed contract for any one of them.
Using a template — the canonical flow
# 1. Pick a template
dodil data table templates
# 2. Create the pipeline-bound table
dodil data table pipeline create entities -b kb-prod --template entity_pii_extraction
# 3. Scope an ingest rule to it — K3 does NOT create one for you.
# -c/--collection carries the PIPELINE id (it maps to CreateRuleRequest.pipeline_id).
dodil data ingest add entities-intake -b kb-prod \
-c "$PIPELINE_ID" -i 'intake/**/*.pdf'
# 4. Upload a document under intake/ — the pipeline extracts rows into the table
dodil data object create ./contract.pdf -b kb-prod -k intake/contracts/acme-2026.pdf
# 5. Query the extracted rows
dodil data sql -b kb-prod "
SELECT entity_type, entity_value FROM entities
WHERE source_key = 'intake/contracts/acme-2026.pdf' AND is_pii = true
"Step 3 is mandatory.
CreateTablePipelinewrites the table entity and the pipeline binding — it explicitly does not auto-create an ingest rule; rule scope is the caller’s job (dodil-k3/bin/api/src/services/pipeline/create_table.rs:12-15). The--folder-prefixflag writes a 0-byte S3 folder marker for the object explorer; it is not rule scoping.
See also
- Tables → CreateTablePipeline — how a template backs a table
- Recipes → Pipeline-bound table — the end-to-end worked example
- Pipelines → Templates — the same catalog, unfiltered
- Concepts → ScriptContract — the typed contract on
Template.contract