Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

All endpoints require authentication and are workspace-scoped. There is no register / create / delete endpoint — hook registration is a config-time operation (via hooks.Register in Go). See the Hooks guide.

List hooks

GET /api/v1/hooks?crew_id=<optional>
Query parameters:
ParamTypeDescription
crew_idstringOptional. Filter to hooks targeting this crew. Cross-tenant IDs return 404.
Response: 200 OK
{
  "rows": [
    {
      "id": "hk_abc123",
      "workspace_id": "ws_123",
      "crew_id": "crw_backend",
      "event": "on_approval_requested",
      "handler_kind": "http",
      "handler_config": {
        "url": "https://hooks.slack.com/services/...",
        "method": "POST",
        "hmac_secret": "redacted_on_read"
      },
      "matcher": {
        "severities": ["warn", "error"]
      },
      "enabled": true,
      "blocking": false,
      "created_by": "user_123",
      "created_at": "2026-03-01T09:00:00Z",
      "updated_at": "2026-04-15T14:22:00Z"
    }
  ],
  "count": 1
}
FieldTypeDescription
rows[].eventstringOne of the 15 lifecycle events. See Hooks guide.
rows[].handler_kindstringshell, http, or subagent.
rows[].handler_configobjectHandler-specific config (URL for http, command for shell, subagent name for subagent).
rows[].matcherobjectOptional filter: tools, agent_ids, crew_ids, severities. Empty = match-all.
rows[].blockingbooleanIf true, a Block outcome short-circuits the triggering operation. Non-blocking runs in a goroutine.
Errors:
StatusCondition
401No workspace.
404crew_id filter points to cross-tenant crew.
500DB error.

Enable

POST /api/v1/hooks/{id}/enable
Auth: OWNER or ADMIN only (403 otherwise). Enabling a hook can invoke shell commands, hit third-party webhooks, or dispatch subagents — the role bar matches that risk. Response: 200 OK
{ "id": "hk_abc123", "enabled": true }
Errors:
StatusCondition
400Missing id.
401Not authenticated.
403Not OWNER/ADMIN.
404Hook not in your workspace.
500DB error.
Emits system.hook_toggled into the journal with the actor’s user ID.

Disable

POST /api/v1/hooks/{id}/disable
Same auth rules, same response shape with "enabled": false.

Registration (Go only)

No HTTP endpoint. Call hooks.Register from workspace provisioning code:
const allowedShell = false // flip to true only when the caller has confirmed OWNER
_, err := hooks.Register(ctx, db, hooks.Hook{
    WorkspaceID: ws,
    Event:       hooks.EventOnApprovalRequested,
    HandlerKind: hooks.HandlerKindHTTP,
    HandlerConfig: map[string]any{
        "url": "https://...",
    },
    Enabled: true,
}, allowedShell)
The trailing allowedShell bool argument is the gate on HandlerKindShell: pass false for any non-OWNER context — the function returns hooks.ErrShellHookNotAllowed if the hook is a shell kind and this flag is false. HTTP / subagent hooks are unaffected by the flag.