{"openapi":"3.1.0","info":{"title":"Ivy API","version":"0.1.0","description":"Ivy traces AWS Lambda functions. This API serves the dashboard and agents. Timestamps are ISO 8601 (UTC, ms precision); durations are milliseconds. Agents can also use the remote MCP server at `/mcp` (Streamable HTTP; same data, compact text answers), or `GET /api/w/{workspace}/p/{project}/traces/{traceId}?format=text` for an LLM-friendly trace."},"servers":[{"url":"/"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"OIDC access token for the API audience, from the issuer in `IVY_OIDC_ISSUER`. Tokens for the MCP audience (`IVY_MCP_RESOURCE`) are only accepted on `/mcp`. Self-hosted setups without OIDC run without auth: no token is needed and `GET /api/config` reports `auth.enabled: false`."},"eventSecret":{"type":"apiKey","in":"header","name":"x-ivy-event-secret","description":"Per-connection secret of the EventBridge API destination."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"Health":{"type":"object","properties":{"ok":{"type":"boolean"},"clickhouse":{"type":"boolean"}},"required":["ok","clickhouse"]},"Config":{"type":"object","properties":{"version":{"type":"string"},"auth":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]},"workspaces":{"type":"object","properties":{"multi":{"type":"boolean","description":"False: one workspace (`default`), no members or invitations."}},"required":["multi"]},"email":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Invitations are also emailed."}},"required":["enabled"]},"aws":{"type":"object","properties":{"quick_create":{"type":"boolean","description":"The publish-cfn-template hook is installed (one-click CloudFormation links)."}},"required":["quick_create"]},"alerts":{"type":"object","properties":{"slack":{"type":"boolean","description":"Slack alerts are configured (IVY_SLACK_CLIENT_ID, IVY_SLACK_CLIENT_SECRET, IVY_PUBLIC_URL, IVY_SECRET_KEY)."},"email":{"type":"boolean","description":"The weekly email digest is configured (IVY_SMTP_URL, IVY_EMAIL_FROM, IVY_PUBLIC_URL)."}},"required":["slack","email"]},"billing":{"type":"object","properties":{"url":{"type":"string","description":"Billing service for Upgrade / Manage billing (IVY_BILLING_URL); absent without one."}},"required":["url"]}},"required":["version","auth","workspaces","email","aws","alerts"]},"Limits":{"type":"object","properties":{"plan":{"type":"string","description":"Plan label; empty when none."},"monthly_trace_quota":{"type":["integer","null"],"description":"Traces per calendar month (UTC); null is unlimited."},"over_quota":{"type":"string","enum":["block","allow"],"description":"`block` rejects ingest at the quota; `allow` keeps accepting."},"source":{"type":"string","enum":["workspace","unset"],"description":"`unset`: the workspace has no limits and is unlimited."}},"required":["plan","monthly_trace_quota","over_quota","source"]},"Usage":{"type":"object","properties":{"workspace":{"type":"string"},"month":{"type":"string","examples":["2026-11"]},"period":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}},"required":["start","end"]},"traces":{"type":"integer","description":"Traces (Lambda invocations) this month, across all projects of the workspace."},"limits":{"$ref":"#/components/schemas/Limits"},"blocked":{"type":"boolean","description":"Ingest is being refused: quota reached with over_quota `block`."}},"required":["workspace","month","period","traces","limits","blocked"]},"Workspace":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","member"]},"default":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}},"required":["id","slug","name","role","default","created_at"]},"WorkspaceList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"}}},"required":["items"]},"WorkspaceCreate":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string","description":"Optional; generated from the name when omitted."}},"required":["name"]},"WorkspaceUpdate":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":[]},"Member":{"type":"object","properties":{"sub":{"type":"string"},"email":{"type":["string","null"]},"role":{"type":"string","enum":["owner","member"]},"you":{"type":"boolean"},"joined_at":{"type":"string","format":"date-time"}},"required":["sub","email","role","you","joined_at"]},"MemberList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}},"required":["items"]},"MemberUpdate":{"type":"object","properties":{"role":{"type":"string","enum":["owner","member"]}},"required":["role"]},"Invitation":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["owner","member"]},"status":{"type":"string","enum":["pending","accepted","revoked","expired"]},"invited_by":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"accepted_at":{"type":["string","null"],"format":"date-time"}},"required":["id","email","role","status","invited_by","created_at","expires_at","accepted_at"]},"InvitationList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}},"required":["items"]},"InvitationCreate":{"type":"object","properties":{"email":{"type":"string"},"role":{"type":"string","enum":["owner","member"]}},"required":["email"]},"InvitationCreated":{"type":"object","properties":{"invitation":{"$ref":"#/components/schemas/Invitation"},"url":{"type":"string","description":"The invite link with its token; returned only here."},"email_sent":{"type":"boolean"},"email_error":{"type":["string","null"]}},"required":["invitation","url","email_sent","email_error"]},"InvitationInfo":{"type":"object","properties":{"workspace":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},"email":{"type":"string"},"role":{"type":"string","enum":["owner","member"]},"status":{"type":"string","enum":["pending","accepted","revoked","expired"]},"invited_by":{"type":["string","null"]},"expires_at":{"type":"string","format":"date-time"}},"required":["workspace","email","role","status","invited_by","expires_at"]},"InvitationAccepted":{"type":"object","properties":{"accepted":{"type":"boolean"},"workspace":{"$ref":"#/components/schemas/Workspace"}},"required":["accepted","workspace"]},"Project":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"archived":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}},"required":["id","slug","name","archived","created_at"]},"ProjectList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}},"required":["items"]},"ProjectCreate":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string","description":"Optional; generated from the name when omitted."}},"required":["name"]},"ProjectUpdate":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"archived":{"type":"boolean"}},"required":[]},"Key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["user","auto-trace","bootstrap"]},"prefix":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"}},"required":["id","name","kind","prefix","created_at","revoked_at"]},"KeyList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Key"}}},"required":["items"]},"KeyCreate":{"type":"object","properties":{"name":{"type":"string"}},"required":[]},"KeyCreated":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string"},"prefix":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"},"key":{"type":"string","description":"The ingest key; returned only here."},"endpoint":{"type":["string","null"]}},"required":["id","name","kind","prefix","created_at","revoked_at","key","endpoint"]},"FunctionSummary":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string"},"project_id":{"type":"string","description":"Workspace-wide routes only."},"project":{"type":["string","null"],"description":"Project slug; workspace-wide routes only."},"invocations":{"type":"integer"},"errors":{"type":"integer"},"error_rate":{"type":"number"},"cold_starts":{"type":"integer"},"avg_ms":{"type":"number"},"p50_ms":{"type":"number"},"p95_ms":{"type":"number"},"p99_ms":{"type":"number"},"last_invoked":{"type":["string","null"],"format":"date-time","description":"null for a function that was only throttled in the range."},"throttles":{"type":"integer","description":"Invocations Lambda rejected (CloudWatch `Throttles`); they never reached the function. 0 when throttle polling is off."}},"required":["name","region","invocations","errors","error_rate","cold_starts","avg_ms","p50_ms","p95_ms","p99_ms","last_invoked"]},"FunctionList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FunctionSummary"}}},"required":["items"]},"Invocation":{"type":"object","properties":{"trace_id":{"type":"string"},"span_id":{"type":"string"},"project_id":{"type":"string","description":"Workspace-wide routes only."},"project":{"type":["string","null"],"description":"Project slug; workspace-wide routes only."},"ts":{"type":"string","format":"date-time"},"function":{"type":"string"},"region":{"type":"string"},"status":{"type":"string","enum":["ok","error","in_progress"],"description":"in_progress: a long-running invocation the extension reported while it ran, without its final record yet. Past deadline (plus 15 s) without one: no completion recorded."},"duration_ms":{"type":"number","description":"For in_progress rows: from the start to last_seen."},"cold_start":{"type":"boolean"},"request_id":{"type":"string"},"trigger":{"type":"string","examples":["aws:apigatewayv2","aws:sqs"]},"http_method":{"type":["string","null"]},"http_path":{"type":["string","null"]},"http_status":{"type":["integer","null"]},"error_type":{"type":["string","null"]},"error_message":{"type":["string","null"]},"memory_used_mb":{"type":["number","null"]},"memory_limit_mb":{"type":["integer","null"]},"failure_phase":{"type":["string","null"],"enum":["init","invoke",null]},"failure_kind":{"type":["string","null"],"enum":["init_failed","out_of_memory","timed_out","crashed",null],"description":"Failure outside the handler, reported by the Ivy extension from the Lambda Telemetry API (labels: Init failed, Out of memory, Timed out, Crashed). Null for successful invocations and ordinary handler errors."},"synthetic":{"type":"boolean","description":"The extension created the invocation span itself because the tracer reported nothing (init failure, crash): the trace has no child spans."},"init_duration_ms":{"type":["number","null"],"description":"Set on cold starts."},"deadline":{"type":["string","null"],"format":"date-time","description":"in_progress rows only: the invocation deadline."},"last_seen":{"type":["string","null"],"format":"date-time","description":"in_progress rows only: when the extension last reported it running."}},"required":["trace_id","span_id","project_id","project","ts","function","region","status","duration_ms","cold_start","request_id","trigger","http_method","http_path","http_status","error_type","error_message","memory_used_mb","memory_limit_mb","failure_phase","failure_kind","synthetic","init_duration_ms","deadline","last_seen"]},"InvocationList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Invocation"}},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page; null on the last page."}},"required":["items","next_cursor"]},"SpanEvent":{"type":"object","properties":{"ts":{"type":"string","format":"date-time"},"name":{"type":"string"},"attributes":{"type":"object","additionalProperties":{"type":"string"}}},"required":["ts","name","attributes"]},"Span":{"type":"object","properties":{"span_id":{"type":"string"},"parent_span_id":{"type":"string","description":"Empty for root spans."},"name":{"type":"string"},"kind":{"type":"string","examples":["SERVER","CLIENT","CONSUMER","PRODUCER","INTERNAL"]},"service":{"type":"string"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"duration_ms":{"type":"number"},"status_code":{"type":"string","enum":["OK","ERROR","UNSET"]},"status_message":{"type":"string"},"attributes":{"type":"object","additionalProperties":{"type":"string"},"description":"Span attributes as stored (strings); JSON-valued ones (`ivy.payload.*`, headers, arrays) are JSON strings. See span-conventions.md. Late Lambda report data (`ivy.billed_duration_ms`, `ivy.memory_max_used_mb`, `ivy.memory_size_mb`) is merged into the invocation span; update spans are never listed themselves."},"resource":{"type":"object","additionalProperties":{"type":"string"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/SpanEvent"}}},"required":["span_id","parent_span_id","name","kind","service","start","end","duration_ms","status_code","status_message","attributes","resource","events"]},"Trace":{"type":"object","properties":{"trace_id":{"type":"string"},"spans":{"type":"array","items":{"$ref":"#/components/schemas/Span"}}},"required":["trace_id","spans"]},"ErrorGroup":{"type":"object","properties":{"fingerprint":{"type":"string","description":"Hash of function, error type, code location (top in-app stack frame) and message template. Pass it as `group` to list invocations."},"function":{"type":"string"},"project_id":{"type":"string","description":"Workspace-wide routes only."},"project":{"type":["string","null"],"description":"Project slug; workspace-wide routes only."},"error_type":{"type":"string"},"error_message":{"type":"string","description":"The latest raw message."},"error_template":{"type":"string","description":"The message with variable parts replaced: `{id}`, `{num}`, `{email}`, `{url}`, `{ip}`, `{date}`, `{path}`, `{str}`."},"count":{"type":"integer"},"variants":{"type":"integer","description":"Distinct raw messages in the range."},"top_messages":{"type":"array","description":"The most frequent raw messages (up to 5), each with its latest trace. Empty for throttles.","items":{"type":"object","properties":{"message":{"type":"string"},"count":{"type":"integer"},"sample_trace_id":{"type":"string"},"last_seen":{"type":"string","format":"date-time"}},"required":["message","count","sample_trace_id","last_seen"]}},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"sample_trace_id":{"type":["string","null"],"description":"null for the synthetic `Throttled` group: throttled requests never reach the function, so there is no trace."},"kind":{"type":"string","enum":["error","throttle"],"description":"`throttle`: one synthetic group per function counting throttles (error_type `Throttled`)."},"failure_kind":{"type":["string","null"],"enum":["init_failed","out_of_memory","timed_out","crashed",null],"description":"Failure outside the handler, reported by the Ivy extension from the Lambda Telemetry API (labels: Init failed, Out of memory, Timed out, Crashed). Null for successful invocations and ordinary handler errors."}},"required":["fingerprint","function","error_type","error_message","error_template","count","variants","top_messages","first_seen","last_seen","sample_trace_id"]},"ErrorGroupList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ErrorGroup"}}},"required":["items"]},"TimeseriesPoint":{"type":"object","properties":{"ts":{"type":"string","format":"date-time"},"invocations":{"type":"integer"},"errors":{"type":"integer"},"p95_ms":{"type":"number"},"throttles":{"type":"integer"}},"required":["ts","invocations","errors","p95_ms","throttles"]},"Timeseries":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TimeseriesPoint"}}},"required":["items"]},"AwsSetup":{"type":"object","properties":{"principal_arn":{"type":["string","null"]},"quick_create":{"type":"boolean"},"events_url":{"type":["string","null"]},"public_url":{"type":["string","null"]},"ingest_endpoint":{"type":["string","null"]},"layer_sha256":{"type":["string","null"]},"default_region":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"sync_interval_seconds":{"type":"integer"},"issues":{"type":"array","items":{"type":"string"}}},"required":["principal_arn","quick_create","events_url","public_url","ingest_endpoint","layer_sha256","default_region","regions","sync_interval_seconds","issues"]},"AwsAccount":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"account_id":{"type":"string"},"role_arn":{"type":"string"},"external_id":{"type":"string"},"stack_name":{"type":"string"},"stack_region":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"all_regions":{"type":"boolean"},"status":{"type":"string","enum":["pending","connected","error"]},"error":{"type":["string","null"],"description":"On a connected account: per-region sync errors, one per line."},"created_at":{"type":"string","format":"date-time"},"verified_at":{"type":["string","null"],"format":"date-time"},"last_sync_at":{"type":["string","null"],"format":"date-time"},"reviewed_at":{"type":["string","null"],"format":"date-time"},"syncing":{"type":"boolean"},"throttle_metrics":{"type":"boolean","description":"Poll CloudWatch for Lambda throttles (GetMetricData, billed to this AWS account)."},"throttle_status":{"type":["string","null"],"enum":["ok","missing_permission","error",null],"description":"`missing_permission`: the stack predates `cloudwatch:GetMetricData`; update the stack with the current template."},"counts":{"type":"object","properties":{"traced":{"type":"integer"},"available":{"type":"integer"},"opted_out":{"type":"integer"},"needs_project":{"type":"integer"},"unsupported":{"type":"integer"},"conflict":{"type":"integer"},"error":{"type":"integer"},"pending":{"type":"integer"},"total":{"type":"integer"},"new":{"type":"integer"}},"required":["traced","available","opted_out","needs_project","unsupported","conflict","error","pending","total","new"]},"quick_create_url":{"type":["string","null"],"description":"Only with the publish-cfn-template hook; carries no parameters or secrets."},"quick_create_error":{"type":["string","null"],"description":"Why there is no quick-create link although the hook exists."},"template_download_url":{"type":"string"}},"required":["id","name","account_id","role_arn","external_id","stack_name","stack_region","regions","all_regions","status","error","created_at","verified_at","last_sync_at","reviewed_at","syncing","throttle_metrics","throttle_status","counts","quick_create_url","quick_create_error","template_download_url"]},"AwsAccountList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AwsAccount"}}},"required":["items"]},"AwsAccountCreate":{"type":"object","properties":{"account_id":{"type":"string","pattern":"^\\d{12}$"},"name":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"all_regions":{"type":"boolean"},"stack_region":{"type":"string"},"throttle_metrics":{"type":"boolean","default":true}},"required":["account_id","regions"]},"AwsAccountUpdate":{"type":"object","properties":{"name":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"all_regions":{"type":"boolean"},"throttle_metrics":{"type":"boolean"},"reviewed":{"type":"boolean","description":"`true` marks the function list as seen."}},"required":[]},"AwsVerifyResult":{"type":"object","properties":{"verified":{"type":"boolean"},"account":{"$ref":"#/components/schemas/AwsAccount"}},"required":["verified","account"]},"AwsDeleteResult":{"type":"object","properties":{"deleted":{"type":"boolean"},"detached":{"type":"boolean"},"detach_errors":{"type":"array","items":{"type":"string"}}},"required":["deleted","detached","detach_errors"]},"AwsFunction":{"type":"object","properties":{"account_id":{"type":"string"},"region":{"type":"string"},"name":{"type":"string"},"arn":{"type":"string"},"runtime":{"type":"string"},"stack":{"type":["string","null"]},"tags":{"type":"object","additionalProperties":{"type":"string"}},"last_modified":{"type":["string","null"]},"state":{"type":"string","enum":["traced","available","opted_out","needs_project","unsupported","conflict","error","pending"]},"reason":{"type":["string","null"]},"project_id":{"type":["string","null"]},"project":{"type":["string","null"]},"source":{"type":["string","null"],"enum":["tag","manual","rule",null],"description":"What decided the tracing state."},"rule_id":{"type":["string","null"]},"manual":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["trace","exclude"]},"project_id":{"type":["string","null"]},"project":{"type":["string","null"]}},"required":["mode","project_id","project"]},{"type":"null"}]},"new":{"type":"boolean"},"first_seen_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["account_id","region","name","arn","runtime","stack","tags","last_modified","state","reason","project_id","project","source","rule_id","manual","new","first_seen_at","updated_at"]},"AwsFunctionList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AwsFunction"}}},"required":["items"]},"AwsFunctionGroups":{"type":"object","properties":{"groups":{"type":"array","items":{"type":"object","properties":{"stack":{"type":["string","null"]},"region":{"type":["string","null"]},"counts":{"type":"object","properties":{"total":{"type":"integer"},"traced":{"type":"integer"},"available":{"type":"integer"},"new":{"type":"integer"}},"required":["total","traced","available","new"]},"rule":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string"},"project":{"type":["string","null"]},"enabled":{"type":"boolean"}},"required":["id","project_id","project","enabled"]},{"type":"null"}]},"suggested_project":{"type":["string","null"]},"functions":{"type":"array","items":{"$ref":"#/components/schemas/AwsFunction"}}},"required":["stack","region","counts","rule","suggested_project","functions"]}}},"required":["groups"]},"AwsFunctionChoice":{"type":"object","properties":{"mode":{"type":"string","enum":["trace","exclude","rules"]},"project":{"type":"string","description":"Slug or ID; required with mode `trace`."}},"required":["mode"]},"AwsFunctionUpdateResult":{"type":"object","properties":{"applied":{"type":"boolean"},"error":{"type":["string","null"]},"function":{"oneOf":[{"$ref":"#/components/schemas/AwsFunction"},{"type":"null"}]}},"required":["applied","error","function"]},"AwsFunctionBulk":{"type":"object","properties":{"functions":{"type":"array","maxItems":500,"items":{"type":"object","properties":{"account_id":{"type":"string"},"region":{"type":"string"},"name":{"type":"string"}},"required":["account_id","region","name"]}},"mode":{"type":"string","enum":["trace","exclude","rules"]},"project":{"type":"string","description":"Slug or ID; required with mode `trace`."}},"required":["functions","mode"]},"RuleMatcher":{"type":"object","properties":{"account_id":{"type":["string","null"],"description":"12-digit AWS account ID, exact."},"region":{"type":["string","null"],"description":"AWS region, exact."},"stack":{"type":["string","null"],"description":"Glob on the CloudFormation stack name (`aws:cloudformation:stack-name` tag)."},"name":{"type":["string","null"],"description":"Glob on the function name; `orders-*` is a prefix match, `*` matches every function."},"tag":{"type":["string","null"],"description":"`key=value` (value may be a glob) or `key`."}},"required":[]},"Rule":{"type":"object","properties":{"id":{"type":"string"},"position":{"type":"integer"},"matcher":{"$ref":"#/components/schemas/RuleMatcher"},"project_id":{"type":"string"},"project":{"type":["string","null"]},"enabled":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}},"required":["id","position","matcher","project_id","project","enabled","created_at"]},"RuleList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Rule"}}},"required":["items"]},"RuleCreate":{"type":"object","properties":{"matcher":{"$ref":"#/components/schemas/RuleMatcher"},"project":{"type":"string","description":"Slug or ID. Every rule names a project: this or `new_project` is required."},"new_project":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name"]},"enabled":{"type":"boolean"},"position":{"type":"integer"}},"required":["matcher"]},"RuleCreated":{"type":"object","properties":{"rule":{"$ref":"#/components/schemas/Rule"},"project":{"$ref":"#/components/schemas/Project"}},"required":["rule","project"]},"RuleUpdate":{"type":"object","properties":{"matcher":{"$ref":"#/components/schemas/RuleMatcher"},"project":{"type":"string"},"enabled":{"type":"boolean"},"position":{"type":"integer"}},"required":[]},"RuleOrder":{"type":"object","properties":{"order":{"type":"array","items":{"type":"string"}}},"required":["order"]},"RuleDryRun":{"type":"object","properties":{"matcher":{"$ref":"#/components/schemas/RuleMatcher"},"project":{"type":"string","description":"May name a project that does not exist yet."}},"required":["matcher"]},"RuleDryRunResult":{"type":"object","properties":{"count":{"type":"integer"},"summary":{"type":"object","properties":{"trace":{"type":"integer"},"unchanged":{"type":"integer"},"excluded":{"type":"integer"},"other":{"type":"integer"},"unsupported":{"type":"integer"}},"required":["trace","unchanged","excluded","other","unsupported"]},"items":{"type":"array","items":{"type":"object","properties":{"function":{"$ref":"#/components/schemas/AwsFunction"},"outcome":{"type":"string","enum":["trace","unchanged","excluded","other","unsupported"]},"project":{"type":["string","null"]}},"required":["function","outcome","project"]}}},"required":["count","summary","items"]},"AlertSettings":{"type":"object","properties":{"slack_enabled":{"type":"boolean"},"interval_minutes":{"type":"integer","minimum":1,"maximum":10080,"description":"At most one message per group this often (default 60)…"},"every_occurrences":{"type":"integer","minimum":1,"maximum":1000000,"description":"…or after this many new occurrences, whichever comes first (default 100)."},"include_throttles":{"type":"boolean","description":"Also alert on the synthetic Throttled groups (default false)."}},"required":["slack_enabled","interval_minutes","every_occurrences","include_throttles"]},"AlertSettingsUpdate":{"type":"object","properties":{"slack_enabled":{"type":"boolean"},"interval_minutes":{"type":"integer"},"every_occurrences":{"type":"integer"},"include_throttles":{"type":"boolean"}},"required":[]},"SlackChannel":{"type":"object","properties":{"id":{"type":"string"},"team_name":{"type":"string"},"channel":{"type":"string"},"status":{"type":"string","enum":["ok","broken"],"description":"`broken` after Slack rejected the webhook (revoked, channel archived)."},"error":{"type":["string","null"]},"configuration_url":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["id","team_name","channel","status","error","configuration_url","created_at"]},"Alerts":{"type":"object","properties":{"available":{"type":"object","properties":{"slack":{"type":"boolean"},"missing":{"type":"array","items":{"type":"string"},"description":"Environment variables Slack still needs."}},"required":["slack","missing"]},"can_edit":{"type":"boolean","description":"Owners change alert settings."},"settings":{"$ref":"#/components/schemas/AlertSettings"},"integrations":{"type":"array","items":{"$ref":"#/components/schemas/SlackChannel"}}},"required":["available","can_edit","settings","integrations"]},"SlackTestResult":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":["string","null"]},"integration":{"$ref":"#/components/schemas/SlackChannel"}},"required":["ok","error","integration"]},"Digest":{"type":"object","properties":{"available":{"type":"boolean"},"missing":{"type":"array","items":{"type":"string"}},"schedule":{"type":"string","description":"Five-field cron, UTC (IVY_DIGEST_CRON; default Monday 08:00)."},"enabled":{"type":"boolean"},"can_edit":{"type":"boolean"},"subscribed":{"type":["boolean","null"],"description":"Whether you get it; null without sign-in."},"recipients":{"type":"integer"}},"required":["available","missing","schedule","enabled","can_edit","subscribed","recipients"]},"DigestUpdate":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]},"DigestPreview":{"type":"object","properties":{"subject":{"type":"string"},"html":{"type":"string"},"text":{"type":"string"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}},"required":["from","to"]},"empty":{"type":"boolean"}},"required":["subject","html","text","period","empty"]},"NotificationItem":{"type":"object","properties":{"workspace":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},"digest":{"type":"boolean"}},"required":["workspace","digest"]},"Notifications":{"type":"object","properties":{"email":{"type":["string","null"]},"digest_available":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/NotificationItem"}}},"required":["email","digest_available","items"]},"NotificationUpdate":{"type":"object","properties":{"workspace":{"type":"string","description":"Slug or ID."},"digest":{"type":"boolean"}},"required":["workspace","digest"]}}},"tags":[{"name":"Workspaces","description":"Workspaces, members and invitations (workspaces-projects.md)."},{"name":"Projects","description":"Projects and their ingest keys."},{"name":"Traces","description":"Functions, invocations, traces, errors and stats, per project (or workspace-wide)."},{"name":"Auto-trace","description":"AWS account connections, opt-in tracing rules and the state of their functions (auto-trace.md)."},{"name":"Alerts","description":"Slack alerts per project, the weekly email digest and your notification settings (alerts.md)."},{"name":"Meta","description":"Health, configuration and this document."}],"paths":{"/api/health":{"get":{"tags":["Meta"],"summary":"Health check","operationId":"getHealth","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/api/config":{"get":{"tags":["Meta"],"summary":"Server configuration for the UI","operationId":"getConfig","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Config"}}}}}}},"/api/openapi.json":{"get":{"tags":["Meta"],"summary":"This OpenAPI document","operationId":"getOpenApi","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/docs":{"get":{"tags":["Meta"],"summary":"API reference page (Scalar)","operationId":"getApiDocs","security":[],"responses":{"200":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/workspaces":{"get":{"tags":["Workspaces"],"summary":"The caller's workspaces","operationId":"listWorkspaces","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceList"}}}}}},"post":{"tags":["Workspaces"],"summary":"Create a workspace (without projects)","operationId":"createWorkspace","description":"The slug is generated from the name (-2, -3, … on collisions). 403 in single-workspace mode.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Single-workspace mode","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slug taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/invitations/{token}":{"get":{"tags":["Workspaces"],"summary":"What an invite link is for","operationId":"getInvitation","parameters":[{"name":"token","in":"path","required":true,"description":"The token from the invite link.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationInfo"}}}},"403":{"description":"Auth is off","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/invitations/{token}/accept":{"post":{"tags":["Workspaces"],"summary":"Accept an invitation","operationId":"acceptInvitation","description":"The signed-in user's verified email must be the invited one (case-insensitive). Single use.","parameters":[{"name":"token","in":"path","required":true,"description":"The token from the invite link.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationAccepted"}}}},"403":{"description":"Other email, or not verified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Used, revoked or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}":{"get":{"tags":["Workspaces"],"summary":"The workspace and your role","operationId":"getWorkspace","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Workspaces"],"summary":"Rename or change the slug (owner)","operationId":"updateWorkspace","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slug taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Workspaces"],"summary":"Delete the workspace (owner)","operationId":"deleteWorkspace","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"confirm","in":"query","description":"Must repeat the slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"AWS accounts connected, or the default workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/members":{"get":{"tags":["Workspaces"],"summary":"Members","operationId":"listMembers","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberList"}}}},"403":{"description":"Single-workspace mode","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/members/{sub}":{"patch":{"tags":["Workspaces"],"summary":"Change a member's role (owner)","operationId":"updateMember","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"sub","in":"path","required":true,"description":"The member's OIDC subject.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Member"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Last owner","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Workspaces"],"summary":"Remove a member (owner), or leave","operationId":"removeMember","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"sub","in":"path","required":true,"description":"The member's OIDC subject.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}}}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Last owner","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/invitations":{"get":{"tags":["Workspaces"],"summary":"Invitations (owner)","operationId":"listInvitations","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"all","in":"query","description":"1 includes accepted, revoked and expired ones.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationList"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Workspaces"],"summary":"Invite by email (owner)","operationId":"createInvitation","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreated"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already a member","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/invitations/{id}":{"delete":{"tags":["Workspaces"],"summary":"Revoke an invitation (owner)","operationId":"revokeInvitation","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Invitation ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/usage":{"get":{"tags":["Workspaces"],"summary":"This month's traces and the workspace's limits","operationId":"getUsage","description":"Traces (Lambda invocations) of all the workspace's projects, per calendar month (UTC). See limits.md.","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/projects":{"get":{"tags":["Projects"],"summary":"Projects","operationId":"listProjects","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"archived","in":"query","description":"1 includes archived projects.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectList"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Projects"],"summary":"Create a project","operationId":"createProject","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"description":"The slug is generated from the name (-2, -3, … on collisions within the workspace).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slug taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}":{"get":{"tags":["Projects"],"summary":"One project","operationId":"getProject","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Projects"],"summary":"Rename, change the slug, archive or unarchive","operationId":"updateProject","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}}],"description":"Any project can be archived, the last active one included. Keys created for an archived project stop working; its data stays until retention, and it can be unarchived.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slug taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/keys":{"get":{"tags":["Projects"],"summary":"Ingest keys of the project","operationId":"listKeys","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"revoked","in":"query","description":"1 includes revoked keys.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyList"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Projects"],"summary":"Create an ingest key (shown once)","operationId":"createKey","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCreated"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Project archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/keys/{id}":{"delete":{"tags":["Projects"],"summary":"Revoke an ingest key","operationId":"revokeKey","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Key ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Key"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The IVY_INGEST_API_KEY key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/functions":{"get":{"tags":["Traces"],"summary":"Function overview for the range","operationId":"listFunctions","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/functions":{"get":{"tags":["Traces"],"summary":"Function overview of every project of the workspace","operationId":"listWorkspaceFunctions","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/invocations":{"get":{"tags":["Traces"],"summary":"Invocations, newest first","operationId":"listInvocations","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}},{"name":"function","in":"query","description":"Exact function name.","schema":{"type":"string"}},{"name":"status","in":"query","description":"Only ok, error or in_progress (still running).","schema":{"type":"string","enum":["ok","error","in_progress"]}},{"name":"q","in":"query","description":"Free text: request ID or trace ID (exact), or text in the error message or HTTP path.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":500,"default":50}},{"name":"cursor","in":"query","description":"Opaque cursor from next_cursor.","schema":{"type":"string"}},{"name":"ids","in":"query","description":"Comma-separated span IDs (up to 100): only these invocations, in their current state (the final row once it arrived). Used by Live to refresh in-progress rows.","schema":{"type":"string"}},{"name":"group","in":"query","description":"An error group fingerprint (from the errors list): only the failed invocations in that group.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvocationList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/invocations":{"get":{"tags":["Traces"],"summary":"Invocations of every project of the workspace, newest first","operationId":"listWorkspaceInvocations","description":"Items carry `project_id` and `project` (slug); open a trace under its project.","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}},{"name":"function","in":"query","description":"Exact function name.","schema":{"type":"string"}},{"name":"status","in":"query","description":"Only ok, error or in_progress (still running).","schema":{"type":"string","enum":["ok","error","in_progress"]}},{"name":"q","in":"query","description":"Free text: request ID or trace ID (exact), or text in the error message or HTTP path.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":500,"default":50}},{"name":"cursor","in":"query","description":"Opaque cursor from next_cursor.","schema":{"type":"string"}},{"name":"ids","in":"query","description":"Comma-separated span IDs (up to 100): only these invocations, in their current state (the final row once it arrived). Used by Live to refresh in-progress rows.","schema":{"type":"string"}},{"name":"group","in":"query","description":"An error group fingerprint (from the errors list): only the failed invocations in that group.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvocationList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/traces/{traceId}":{"get":{"tags":["Traces"],"summary":"All spans of a trace","operationId":"getTrace","description":"Spans sorted by start time. With `format=text`, a compact text tree for LLMs (see mcp.md and the @ivy/format package).","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"traceId","in":"path","required":true,"description":"32 hex characters.","schema":{"type":"string"}},{"name":"format","in":"query","description":"`json` (default) or `text`.","schema":{"type":"string","enum":["json","text"],"default":"json"}},{"name":"detail","in":"query","description":"Text format only: summary, normal or full.","schema":{"type":"string","enum":["summary","normal","full"],"default":"normal"}},{"name":"max_tokens","in":"query","description":"Text format only: approximate size budget; 0 for no limit.","schema":{"type":"integer","minimum":0,"default":4000}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trace"}},"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"Trace (or workspace, project) not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/errors":{"get":{"tags":["Traces"],"summary":"Error groups (function + error type + code location + message template), plus one `Throttled` group per throttled function","operationId":"listErrorGroups","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}},{"name":"function","in":"query","description":"Exact function name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorGroupList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/errors":{"get":{"tags":["Traces"],"summary":"Error groups of every project of the workspace","operationId":"listWorkspaceErrorGroups","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}},{"name":"function","in":"query","description":"Exact function name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorGroupList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/stats/timeseries":{"get":{"tags":["Traces"],"summary":"Invocations, errors, p95 and throttles per bucket","operationId":"getTimeseries","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}},{"name":"function","in":"query","description":"Exact function name.","schema":{"type":"string"}},{"name":"bucket","in":"query","description":"Bucket size; default keeps about 100 points or fewer.","schema":{"type":"string","enum":["1m","5m","15m","1h","1d"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timeseries"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/stats/timeseries":{"get":{"tags":["Traces"],"summary":"Invocations, errors, p95 and throttles per bucket, over every project of the workspace","operationId":"getWorkspaceTimeseries","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"since","in":"query","description":"Relative range: a number plus m, h or d (e.g. 15m, 1h, 24h, 7d). Default 24h.","schema":{"type":"string","pattern":"^\\d+[mhd]$","default":"24h"}},{"name":"from","in":"query","description":"Range start (ISO 8601); overrides since.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Range end (ISO 8601). Default now.","schema":{"type":"string","format":"date-time"}},{"name":"function","in":"query","description":"Exact function name.","schema":{"type":"string"}},{"name":"project","in":"query","description":"Slug or ID: only this project (for a function name that exists in several projects).","schema":{"type":"string"}},{"name":"bucket","in":"query","description":"Bucket size; default keeps about 100 points or fewer.","schema":{"type":"string","enum":["1m","5m","15m","1h","1d"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timeseries"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Workspace or project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/setup":{"get":{"tags":["Auto-trace"],"summary":"Server-side configuration for the connect flow","operationId":"getAwsSetup","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsSetup"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/template.yaml":{"get":{"tags":["Auto-trace"],"summary":"A connection's CloudFormation template (contains its event secret)","operationId":"getAwsTemplate","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"account","in":"query","description":"Connection ID: that connection's values as parameter defaults.","schema":{"type":"string"}},{"name":"download","in":"query","description":"1 adds content-disposition: attachment.","schema":{"type":"string"}}],"responses":{"200":{"description":"Template","content":{"text/yaml":{"schema":{"type":"string"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/me/notifications":{"get":{"tags":["Alerts"],"summary":"Your digest subscription per workspace","operationId":"getNotifications","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Notifications"}}}},"403":{"description":"Auth is off","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Alerts"],"summary":"Subscribe to or unsubscribe from a workspace's digest","operationId":"updateNotifications","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationItem"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Auth is off","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/alerts":{"get":{"tags":["Alerts"],"summary":"Alert settings and Slack channels of the project","operationId":"getAlerts","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alerts"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Alerts"],"summary":"Change the alert settings (owner)","operationId":"updateAlerts","description":"Partial update. A message is sent when a group is first seen, then at most every `interval_minutes` or every `every_occurrences` occurrences, whichever comes first.","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertSettingsUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertSettings"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/alerts/slack/connect":{"post":{"tags":["Alerts"],"summary":"Start \"Add to Slack\" (owner)","operationId":"connectSlack","description":"Returns Slack's OAuth v2 authorize URL (scope `incoming-webhook`) with a signed state valid for 10 minutes, and sets a cookie that the callback checks.","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slack is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/alerts/slack/{id}":{"delete":{"tags":["Alerts"],"summary":"Remove a Slack channel (owner)","operationId":"removeSlackChannel","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Channel ID (slk_…).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}}}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/p/{project}/alerts/slack/{id}/test":{"post":{"tags":["Alerts"],"summary":"Send a test message (owner)","operationId":"testSlackChannel","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"project","in":"path","required":true,"description":"Project slug or ID within the workspace.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Channel ID (slk_…).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlackTestResult"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slack is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/slack/oauth/callback":{"get":{"tags":["Alerts"],"summary":"Slack OAuth redirect","operationId":"slackOAuthCallback","security":[],"description":"Checks the signed state and the cookie from connect, exchanges the code (oauth.v2.access), stores the webhook encrypted and redirects to the project's alert settings with `?slack=connected|denied|error`.","parameters":[{"name":"code","in":"query","description":"From Slack.","schema":{"type":"string"}},{"name":"state","in":"query","description":"From connect.","schema":{"type":"string"}},{"name":"error","in":"query","description":"From Slack when the user cancelled.","schema":{"type":"string"}}],"responses":{"302":{"description":"Back to the alert settings"},"400":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}},"409":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/w/{workspace}/digest":{"get":{"tags":["Alerts"],"summary":"The weekly email digest of the workspace","operationId":"getDigest","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Digest"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Alerts"],"summary":"Switch the digest on or off (owner)","operationId":"updateDigest","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigestUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigestUpdate"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Only workspace owners can do this","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/digest/preview":{"get":{"tags":["Alerts"],"summary":"Preview the digest (the last seven days)","operationId":"previewDigest","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigestPreview"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/digest/unsubscribe":{"get":{"tags":["Alerts"],"summary":"Unsubscribe page (link in the digest)","operationId":"getUnsubscribe","security":[],"parameters":[{"name":"token","in":"query","description":"Signed token from the email.","schema":{"type":"string"}}],"responses":{"200":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}},"400":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"tags":["Alerts"],"summary":"Unsubscribe (also RFC 8058 one-click)","operationId":"unsubscribe","security":[],"parameters":[{"name":"token","in":"query","description":"Signed token from the email.","schema":{"type":"string"}}],"responses":{"200":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}},"400":{"description":"HTML page","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/aws/events":{"post":{"tags":["Auto-trace"],"summary":"EventBridge API destination target","operationId":"postAwsEvent","description":"Syncs the region of the event. Authenticated with the per-connection event secret, not user auth.","security":[{"eventSecret":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"202":{"description":"Accepted"},"401":{"description":"Missing secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Wrong secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/accounts":{"get":{"tags":["Auto-trace"],"summary":"Connected AWS accounts","operationId":"listAwsAccounts","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsAccountList"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Auto-trace"],"summary":"Start connecting an AWS account (traces nothing yet)","operationId":"createAwsAccount","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsAccountCreate"}}}},"responses":{"201":{"description":"Created (status pending)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsAccount"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Account already connected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/accounts/{id}":{"get":{"tags":["Auto-trace"],"summary":"One connection","operationId":"getAwsAccount","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Connection ID (not the AWS account ID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsAccount"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Auto-trace"],"summary":"Update a connection","operationId":"updateAwsAccount","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Connection ID (not the AWS account ID).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsAccountUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsAccount"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Auto-trace"],"summary":"Remove a connection","operationId":"deleteAwsAccount","description":"Removes the layer from all functions first unless detach=false (or the account is pending).","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Connection ID (not the AWS account ID).","schema":{"type":"string"}},{"name":"detach","in":"query","description":"Detach the layer first (default true).","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsDeleteResult"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/accounts/{id}/verify":{"post":{"tags":["Auto-trace"],"summary":"Try AssumeRole; on success the account becomes connected","operationId":"verifyAwsAccount","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Connection ID (not the AWS account ID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsVerifyResult"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/accounts/{id}/sync":{"post":{"tags":["Auto-trace"],"summary":"Sync the functions of a connection","operationId":"syncAwsAccount","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Connection ID (not the AWS account ID).","schema":{"type":"string"}},{"name":"wait","in":"query","description":"1 waits for the sync to finish.","schema":{"type":"string"}}],"responses":{"202":{"description":"Started","content":{"application/json":{"schema":{"type":"object","properties":{"started":{"type":"boolean"}}}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Account pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/accounts/{id}/functions":{"get":{"tags":["Auto-trace"],"summary":"A connection's functions grouped by CloudFormation stack","operationId":"listAwsAccountFunctions","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Connection ID (not the AWS account ID).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsFunctionGroups"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/functions":{"get":{"tags":["Auto-trace"],"summary":"Every known function of the workspace","operationId":"listAwsFunctions","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"account","in":"query","description":"12-digit AWS account ID.","schema":{"type":"string"}},{"name":"project","in":"query","description":"Slug or ID: functions sending to it.","schema":{"type":"string"}},{"name":"state","in":"query","description":"Tracing state.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsFunctionList"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/functions/bulk":{"post":{"tags":["Auto-trace"],"summary":"The same manual choice for many functions","operationId":"bulkUpdateAwsFunctions","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsFunctionBulk"}}}},"responses":{"202":{"description":"Stored; applied by a sync","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"}}}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/functions/{accountId}/{region}/{name}":{"put":{"tags":["Auto-trace"],"summary":"Manual choice for one function: trace into a project, exclude, or follow the rules","operationId":"updateAwsFunction","description":"Stores the choice, then applies it right away. If applying fails the choice is kept and the next sync retries.","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"accountId","in":"path","required":true,"description":"12-digit AWS account ID.","schema":{"type":"string"}},{"name":"region","in":"path","required":true,"description":"AWS region.","schema":{"type":"string"}},{"name":"name","in":"path","required":true,"description":"Function name.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsFunctionChoice"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsFunctionUpdateResult"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/rules":{"get":{"tags":["Auto-trace"],"summary":"Auto-trace rules, in evaluation order","operationId":"listRules","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleList"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Auto-trace"],"summary":"Create a rule (optionally with a new project); re-syncs","operationId":"createRule","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleCreated"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/rules/dry-run":{"post":{"tags":["Auto-trace"],"summary":"Which functions a matcher selects, and what a rule with it would change","operationId":"dryRunRule","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleDryRun"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleDryRunResult"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/rules/order":{"put":{"tags":["Auto-trace"],"summary":"Reorder rules; re-syncs","operationId":"reorderRules","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleOrder"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleList"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/w/{workspace}/aws/rules/{id}":{"patch":{"tags":["Auto-trace"],"summary":"Update a rule; re-syncs","operationId":"updateRule","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Rule ID.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rule"}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Auto-trace"],"summary":"Delete a rule; re-syncs (functions only it selected are detached)","operationId":"deleteRule","parameters":[{"name":"workspace","in":"path","required":true,"description":"Workspace slug or ID.","schema":{"type":"string"}},{"name":"id","in":"path","required":true,"description":"Rule ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"404":{"description":"Not found (also: workspace you are not a member of)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}