Skip to Content
We are live but in Staging 🎉

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.

RPCHTTP
CreateRulePOST /:bucket/rules
GetRuleGET /:bucket/rules/:rule_id
ListRulesGET /:bucket/rules
UpdateRulePATCH /:bucket/rules/:rule_id
DeleteRuleDELETE /:bucket/rules/:rule_id

gRPC setup — grpcurl, endpoints, reflection, and field-name casing — is covered once in Conventions → Using gRPC.

CreateRule

Request

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

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_idbinding is empty if the pipeline was deleted. See Core Concepts → Rule.

ListRules

Filter by source_id and/or pipeline_id. Cursor pagination.

Request

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

{ "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

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

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