Rules — API Reference
Package: dodil.k3.ingest.v1 · Service: IngestService
A rule is a trigger: glob/MIME/size filters that bind a source to a pipeline. When an object matches, K3 spawns an ingest job that runs the bound pipeline. See Core Concepts → Rule.
| RPC | HTTP |
|---|---|
CreateRule | POST /:bucket/rules |
GetRule | GET /:bucket/rules/:rule_id |
ListRules | GET /:bucket/rules |
UpdateRule | PATCH /:bucket/rules/:rule_id |
DeleteRule | DELETE /:bucket/rules/:rule_id |
gRPC setup —
grpcurl, endpoints, reflection, and field-name casing — is covered once in Conventions → Using gRPC.
CreateRule
Request
HTTP
curl -sS -X POST "https://k3.dev.dodil.io/kb-prod/rules" \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bucket": "kb-prod",
"sourceId": "src_a1b2...",
"name": "pdf-contracts",
"description": "All PDFs in contracts/",
"includePatterns": ["contracts/**/*.pdf"],
"excludePatterns": ["contracts/**/draft-*"],
"includeMimeTypes": ["application/pdf"],
"minSizeBytes": "1024",
"maxSizeBytes": "0",
"enabled": true,
"priority": 100,
"pipelineId": "pipe_a1b2..."
}'Matching is conjunctive across axes (path globs ∧ MIMEs ∧ size). Within an axis, includes OR together; excludes always win. See Core Concepts → Glob pattern syntax for the full grammar (tokens, case-insensitivity, MIME wildcard, evaluation order) — important: patterns are ASCII case-insensitive.
Response
An IngestRule row — see Core Concepts → Rule.
GetRule
Request
HTTP
curl -sS "https://k3.dev.dodil.io/kb-prod/rules/rule_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN"Response
An IngestRule row with server-derived binding (pipeline name, kind, destination) for display. Always route on pipeline_id — binding is empty if the pipeline was deleted. See Core Concepts → Rule.
ListRules
Filter by source_id and/or pipeline_id. Cursor pagination.
Request
HTTP
All rules tied to one source:
curl -sS "https://k3.dev.dodil.io/kb-prod/rules?source_id=src_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN"All rules tied to one pipeline:
curl -sS "https://k3.dev.dodil.io/kb-prod/rules?pipeline_id=pipe_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN"Response
HTTP
{
"rules": [
{
"ruleId": "rule_a1b2...",
"bucket": "kb-prod",
"sourceId": "src_a1b2...",
"name": "pdf-contracts",
"includePatterns": ["contracts/**/*.pdf"],
"enabled": true,
"priority": 100,
"pipelineId": "pipe_a1b2..."
}
],
"pagination": { "nextPageToken": "", "totalCount": "1" }
}UpdateRule
Patch-style. Repeated fields use the StringList wrapper from dodil.k3.common.v1 so absent / empty / non-empty have distinct meanings.
Request
HTTP
Disable a rule without deleting it:
curl -sS -X PATCH "https://k3.dev.dodil.io/kb-prod/rules/rule_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "bucket": "kb-prod", "ruleId": "rule_a1b2...", "enabled": false }'Tighten the include set:
curl -sS -X PATCH "https://k3.dev.dodil.io/kb-prod/rules/rule_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bucket": "kb-prod",
"ruleId": "rule_a1b2...",
"includePatterns": { "values": ["contracts/2026/*.pdf"] }
}'Re-bind to a new pipeline:
curl -sS -X PATCH "https://k3.dev.dodil.io/kb-prod/rules/rule_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "bucket": "kb-prod", "ruleId": "rule_a1b2...", "pipelineId": "pipe_new..." }'Response
An IngestRule row — see Core Concepts → Rule.
DeleteRule
Request
HTTP
curl -sS -X DELETE "https://k3.dev.dodil.io/kb-prod/rules/rule_a1b2..." \
-H "Authorization: Bearer $DODIL_TOKEN"Response
Empty (DeleteRuleResponse {}).
Deleting a rule stops new ingests under it. Existing jobs stay in the system with their rule_id pointing at the deleted row.
See also
- Sync — trigger discovery and ingestion on a source
- Jobs — one-shot ingest of a single object
- Core Concepts → Rule — full
IngestRule+PipelineBindingtypes grpcurlreference — full flag set + reflection-disabled fallbacks