API reference · Hubtask API 0.1.0
automation
GET /automation/rules
The workspace's automation rules
Newest first, and only the rules the caller may see: a member manages their own rules, and an administrator the scope's. Deleted rules are not among them - the deletion is soft so that the runs a rule produced stay readable, not so that the rule stays listed.
Query parameters
Responses
200The rules AutomationRulePage4XXAn error per RFC 9457 Problem
curl -X GET "$HUBTASK_URL/automation/rules" \ -H "Authorization: Bearer $HUBTASK_TOKEN" POST /automation/rules
Write a rule
A rule is created switched off. Enabling it is its own call and its own audit entry: writing what a rule would do and letting it loose on the workspace are two decisions, and a rule that ran the moment it was saved would give nobody the chance to read it back first. Writing a rule needs the automation permission at its scope and the rights its own actions need. Without the second half a member with automation rights and nothing else would write a rule that runs as a generously-scoped service account and does what they may not. What this build refuses, and says so by code rather than by silence: a condition that does not compile, or that names something this build does not publish; an action naming a kind this build does not serve; a parameter the action's use case does not declare.
Headers
Request body application/json — AutomationRuleCreate
Responses
201Written, and switched off AutomationRule4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "scope": { "type": "TENANT" }, "run_as": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c", "trigger": { "kind": "EVENT" }, "conditions": [ { "expr": "string" } ], "actions": [ { "kind": "string" } ], "throttle": {}, "on_error": "STOP"}' GET /automation/rules/{ruleId}
One rule, as it stands
Path parameters
Responses
200The rule AutomationRule4XXAn error per RFC 9457 Problem
curl -X GET "$HUBTASK_URL/automation/rules/{ruleId}" \ -H "Authorization: Bearer $HUBTASK_TOKEN" PATCH /automation/rules/{ruleId}
Change what a rule does
An omitted field is left alone. enabled is not among the fields: switching a rule on or off is its own call, so that the audit trail says which of the two somebody did rather than leaving it to be inferred from a change set. The same two-sided permission check as creating one, against the rule as it would be afterwards - a rule may not be edited into doing something its writer may not do.
Path parameters
Request body application/merge-patch+json — AutomationRuleUpdate
Responses
200The rule as it now stands AutomationRule4XXAn error per RFC 9457 Problem
curl -X PATCH "$HUBTASK_URL/automation/rules/{ruleId}" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{ "name": "string", "scope": { "type": "TENANT" }, "run_as": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c", "trigger": { "kind": "EVENT" }, "conditions": [ { "expr": "string" } ], "actions": [ { "kind": "string" } ], "throttle": {}, "on_error": "STOP", "expected_version": 1}' DELETE /automation/rules/{ruleId}
Remove a rule
A soft delete. The rule stops matching anything at once and disappears from the listing, and the runs it produced stay readable: a run log whose rule vanished would be a record of actions nobody can account for.
Path parameters
Responses
204Removed4XXAn error per RFC 9457 Problem
curl -X DELETE "$HUBTASK_URL/automation/rules/{ruleId}" \ -H "Authorization: Bearer $HUBTASK_TOKEN" POST /automation/rules/{ruleId}:enable
Switch a rule on
Its own call and its own audit entry, on both sides. Letting a rule act on the workspace is the decision worth recording, and the permission is re-checked here rather than trusted from whenever the rule was written: the writer's rights may have narrowed since. Enabling also clears the failure counter, because a rule somebody has looked at and turned back on is a rule whose run of failures has been dealt with.
Path parameters
Headers
Responses
200On AutomationRule4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules/{ruleId}:enable" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /automation/rules/{ruleId}:disable
Switch a rule off
The rule stays, and stops acting. What a run of failures does automatically, a person can do deliberately - and the trail says which of the two it was.
Path parameters
Headers
Responses
200Off AutomationRule4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules/{ruleId}:disable" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /automation/rules:check
Check every rule of the workspace against what exists now
Every rule the caller may read, its references resolved - the trigger's event type, each action's kind and parameter keys, each condition, the account it runs as, and every identifier a parameter carries - against what this installation and this workspace have now. What is found is written on the rules (findings, checked_at) and answered here; a rule that cannot run is switched off, audited and its author told, exactly as five failed runs would. Nothing else is written. The rules screen calls this when it opens, which is what makes "after an update, the rules that need attention are shown" true without anything enumerating tenants. A deletion of something a rule may name runs the same check for the workspace by itself.
Responses
200The rules, each with what the check found4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules:check" \ -H "Authorization: Bearer $HUBTASK_TOKEN" POST /automation/rules:test
Dry-run a rule against a sample event
A dry run: a sample event in, which conditions matched and which actions would run out - and no side effects, with the restore's dry-run discipline behind the promise: nothing below this route opens a writing transaction. No action dispatches, nothing is queued, and the run log records nothing. Test either a stored rule by its identifier or a definition you are about to save - the same document POST /automation/rules takes, checked by the same validation, so a rule the dry run accepts is a rule the create will accept. Both arms of every branch are reported with whether they would run, which is more than a real run's log shows: the run records the path it took, and the dry run answers the question "and what if it had not".
Request body application/json — RuleTest
Responses
200What the rule would have done RuleTestResult4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules:test" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "rule_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c", "rule": { "name": "string", "scope": { "type": "TENANT" }, "run_as": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c", "trigger": { "kind": "EVENT" }, "actions": [ {} ] }, "sample_event": { "type": "string" }, "payload": {}}' POST /automation/rules/{ruleId}:trigger
Run a rule now
The MANUAL trigger: the one of the six a person pulls. It queues a run into the same engine every other trigger produces into - the conditions are evaluated, the actions dispatch as the rule's run_as account, and the loop bound and the throttle apply exactly as they do to an event's run. The run records who pulled it, which is the whole reason this is its own call rather than a flag on something else: a rule that acted because somebody asked and a rule that acted because a deadline passed are two different entries in the log. Only a rule whose trigger is MANUAL can be started this way, and only an enabled one. Both refusals name themselves rather than answering an empty success - a call that appears to work and does nothing is the failure this refusal exists to avoid. The answer carries the identifier the run will have. It is a 202: the run happens on a worker, so GET /automation/runs/{runId} answers 404 until it starts and the whole log afterwards.
Path parameters
Headers
Responses
202Queued, with the identifier the run will carry RuleRunAccepted4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules/{ruleId}:trigger" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /automation/rules/{ruleId}:rotate-inbound-token
Mint the address an inbound-webhook rule answers on
The INBOUND_WEBHOOK trigger's credential: a token-protected URL per rule, minted here and answered once. It is stored hashed under its own purpose label, so no later read can produce it. Rotating is how one is revoked. There is exactly one address per rule and the replacement happens in a single statement, so the old token and the new one never both open the rule - which is what "revocable by rotating" has to mean. Somebody who wants to revoke without a replacement switches the rule off. Only a rule whose trigger is INBOUND_WEBHOOK. An address on any other rule would be a credential that opens nothing, handed out as though it worked.
Path parameters
Headers
Responses
200Minted, with the token shown for the only time InboundTriggerToken4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/rules/{ruleId}:rotate-inbound-token" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /automation/inbound/{token}
Start a rule from outside
The other half of the INBOUND_WEBHOOK trigger: an external system posts here and the rule's run begins, in the same engine every other trigger produces into. This authenticates the rule, never a person. There is no account behind the token and it grants nothing beyond starting that one rule - the run carries no actor, because naming one would invent an author for something nobody did. What the run may then do is its run_as account's business, checked per action exactly as it is for every other trigger. The body is a JSON object and enters the condition language as payload, as data: it is never rendered as an instruction to anything. It is bounded well below the request limit, because what bounds a transfer and what bounds an evaluation are two different numbers - anything larger is refused rather than truncated. An unknown token, a rotated one, a rule that has been deleted, a rule that is switched off and a rule whose trigger is no longer an inbound webhook all answer the same 404 with the same body. Distinguishing them would answer questions to whoever is trying tokens.
Path parameters
Request body application/json
Responses
202Queued, with the identifier the run will carry RuleRunAccepted4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/inbound/{token}" \ -H "Content-Type: application/json" \ -d '{}' GET /automation/runs
What the rules have done
Every run, newest first: which rule, which event started it, how its conditions answered, what each action did, and what went wrong if anything did. This is the run log - retrievable, filterable, and the only place a person can find out why a rule did or did not act. A run outlives the rule that produced it. Deleting a rule is soft for exactly this reason: a record of actions nobody can account for would be worse than the rule staying visible.
Query parameters
Responses
200The runs RuleRunPage4XXAn error per RFC 9457 Problem
curl -X GET "$HUBTASK_URL/automation/runs" \ -H "Authorization: Bearer $HUBTASK_TOKEN" GET /automation/runs/{runId}
One run, with every condition and every action
POST /automation/runs/{runId}:replay
Complete a failed run
Re-executes a failed run's remaining actions under the same idempotency keys - which is what makes this a completion rather than a duplication: an action the original run finished finds its key already claimed and does nothing again, and only what never happened happens now. Only a FAILED run can be replayed, and only while its rule is enabled: a waiting run resumes by itself, a skipped or throttled one did what its rule says, and a disabled rule must not act. The conditions are evaluated again against the world as it stands - the answer that decides an action is the answer of the day it runs - and the replay is audited with the replayer, because somebody looked at a failure and decided the world is ready for the rest. The answer carries the identifier the replay's run will have, exactly as :trigger does.
Path parameters
Headers
Responses
202Queued, with the identifier the replay's run will carry RuleRunAccepted4XXAn error per RFC 9457 Problem
curl -X POST "$HUBTASK_URL/automation/runs/{runId}:replay" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /integrations/http-requests
Call an external HTTP address
One outbound call, through the guarded client: private and link-local ranges are refused unless the installation released them, redirects are limited, the call has a deadline and the response a size cap - and the response is then discarded, because a rule cannot read an answer. The header secret is sealed at rest and masked everywhere after creation. This is also what a rule's HTTP_REQUEST action performs: the rule carries the request, and the run supplies the event its body template is rendered from. The call happens on a job with the webhook ladder's retries; the answer is a JobRef to poll.
Request body application/json — HttpRequestCall
curl -X POST "$HUBTASK_URL/integrations/http-requests" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "method": "GET", "url": "string", "headers": {}, "secret_header_name": "string", "secret_header_value": "string", "signature_header": "string", "body_template": "string", "event_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c"}'