{"openapi":"3.1.0","info":{"title":"Dharta API","version":"2025-05-18","description":"Public API for managing Dharta organizations: API keys, model\nkeys (BYOK provider credentials), webhook endpoints, usage,\nand billing.\n\nAuth: either a Devise session cookie (for browser dashboard\ncalls) or a Bearer API key (`dh_live_…`) for headless / SDK\ncalls. Internal control-plane endpoints (`/internal/*`) are\nservice-token gated and intentionally omitted here — they\nare not customer-facing.\n","contact":{"name":"Dharta Support","url":"https://dharta.ai"}},"servers":[{"url":"https://dharta.ai","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"dh_live_…","description":"API key issued to an organization. Format: `dh_live_` followed\nby 32 lowercase alphanumeric characters. Send as\n`Authorization: Bearer dh_live_…`. Fine-grained operation\nscopes are enforced server-side per route.\n"},"cookieAuth":{"type":"apiKey","in":"cookie","name":"_karta_session","description":"Devise session cookie used by the web dashboard."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable detail."},"details":{"type":"object","additionalProperties":true}}},"ApiKey":{"type":"object","required":["id","name","prefix","scopes","mode","expires_at","created_at"],"properties":{"id":{"type":"integer","description":"Numeric API key id."},"name":{"type":"string","maxLength":200},"prefix":{"type":"string","example":"dh_live_abc123","description":"Visible prefix; the full secret is shown only once at creation."},"scopes":{"type":"array","items":{"type":"string","enum":["agents:read","appearance:read","analytics:read","billing:read","caps:read","directories:read","embed_keys:read","env:read","instance_env:read","kartas:read","keys:read","members:read","model_connections:read","releases:read","schedules:read","sessions:read","source_repos:read","webhooks:read","fleet:read","agents:write","appearance:write","env:write","fleet:write","instance_env:write","kartas:write","organization:write","releases:write","schedules:write","embed_keys:write","caps:write","source_repos:write","env:secrets:read","source_archives:read","workspace_tokens:create","workspace:read","audit_log:export","fleet:subjects:read","members:invite","members:write","members:owner_role:write","agents:delete","keys:write","model_connections:write","fleet:subjects:write","organization:support_access:write","fleet:operations:write","webhooks:write"]}},"mode":{"type":"string","enum":["live","test"],"description":"Which environment the key authenticates against. A rotation keeps the original's mode."},"expires_at":{"type":["string","null"],"format":"date-time","description":"`null` when the key never expires. A key holding a sensitive scope always carries one."},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"}}},"ModelConnection":{"type":"object","required":["id","slug","provider","name","tail","credential_kind","funding_source","owner_kind","storage_kind","adapter_kind","endpoint_url","api_format","connector_access_path_revision","connector_access_path_digest","created_at","last_verified_at","verification_error","revoked_at"],"properties":{"id":{"type":"integer","description":"Numeric model connection id. Agent model overrides use the connection's canonical connector slug."},"slug":{"type":"string","maxLength":63,"pattern":"^(?!\\d+$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$","description":"Organization-unique connection slug. Every `/model_connections/{id}` path accepts it in place of the numeric id, and model references spell it `connector:<slug>/<model>`. Never only digits, because an all-digit path segment is read as the id."},"adapter_kind":{"type":"string","description":"Provider access path this connector uses, derived from its provider and API format."},"provider":{"type":"string","enum":["anthropic","openai","openrouter","xai","google"]},"name":{"type":"string","maxLength":200},"tail":{"type":"string","description":"Last 4 chars of the plaintext, shown for identification."},"credential_kind":{"type":"string","enum":["api_key"]},"funding_source":{"type":"string","enum":["api_usage"]},"owner_kind":{"type":"string","enum":["organization"]},"storage_kind":{"type":"string","enum":["control_plane_encrypted"]},"endpoint_url":{"type":["string","null"],"format":"uri"},"api_format":{"type":["string","null"],"enum":["anthropic_messages","openai_chat_completions","openai_responses",null]},"connector_access_path_revision":{"type":"integer","minimum":1},"connector_access_path_digest":{"type":"string","pattern":"^[0-9a-f]{64}$"},"created_at":{"type":"string","format":"date-time"},"last_verified_at":{"type":["string","null"],"format":"date-time"},"verification_error":{"type":["string","null"]},"revoked_at":{"type":["string","null"],"format":"date-time"}}},"UserModelConnection":{"type":"object","additionalProperties":false,"required":["id","name","provider","capability_id","adapter_kind","required_harness_type","agent_id","release_version","credential_kind","funding_source","owner_kind","storage_kind","execution_scope","status","status_reason","provider_account_label","authorization_revision","last_status_at","last_successful_probe_at","logout_requested_at","logged_out_at","revoked_at","created_at","updated_at"],"properties":{"id":{"type":"integer"},"agent_id":{"type":"integer","minimum":1},"release_version":{"type":"integer","minimum":1},"name":{"type":"string","maxLength":100},"provider":{"type":"string","enum":["openai","xai"]},"capability_id":{"type":"string","enum":["openai_codex_hosted_subscription","xai_grok_hosted_subscription"]},"adapter_kind":{"type":"string","enum":["openai_codex_app_server","xai_grok_build_acp"]},"required_harness_type":{"type":"string","enum":["codex-cli","grok-build"]},"credential_kind":{"type":"string","enum":["provider_managed_session"]},"funding_source":{"type":"string","enum":["subscription_entitlement"]},"owner_kind":{"type":"string","enum":["individual"]},"storage_kind":{"type":"string","enum":["provider_client_owned"]},"execution_scope":{"type":"string","enum":["private_interactive"]},"status":{"type":"string","enum":["pending_login","ready","reauthorization_required","logout_pending","logged_out","error","revoked"]},"status_reason":{"type":["string","null"],"maxLength":128},"provider_account_label":{"type":["string","null"],"maxLength":255},"authorization_revision":{"type":"integer","minimum":1},"last_status_at":{"type":["string","null"],"format":"date-time"},"last_successful_probe_at":{"type":["string","null"],"format":"date-time"},"logout_requested_at":{"type":["string","null"],"format":"date-time"},"logged_out_at":{"type":["string","null"],"format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ConnectorOffers":{"type":"object","required":["connector","models"],"properties":{"connector":{"type":"object","required":["id","slug","provider"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"provider":{"type":"string","enum":["anthropic","openai","openrouter","xai","google","bedrock","vertex"]}}},"models":{"type":"array","description":"Every candidate for this connector: the provider catalog, then any configured offer the catalog does not carry.","items":{"type":"object","required":["model_id","enabled","default"],"properties":{"model_id":{"type":"string"},"enabled":{"type":"boolean"},"default":{"type":"boolean","description":"True for the connector default. At most one model is the default, and it may be absent."}}}}}},"ConnectorOffersRequest":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"array","items":{"type":"string"},"description":"Replaces the whole enabled set. An empty array disables every model on this connector."},"default":{"type":["string","null"],"description":"Connector default. Must be one of `enabled`. Omit it or send null to clear it."}}},"OrganizationModelSettings":{"type":"object","required":["connector_order","model_reference","model_parameters","provider_endpoint_kind","resolved"],"properties":{"connector_order":{"type":"array","items":{"type":"string"},"description":"Stored ordered connector slugs. `[]` means unset, which resolves as `[\"karta\"]`."},"model_reference":{"type":"string","description":"Stored model reference in shorthand. `\"\"` when unset."},"model_parameters":{"type":"object","additionalProperties":false,"properties":{"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","exclusiveMinimum":0,"maximum":1},"max_output_tokens":{"type":"integer","minimum":1,"maximum":1000000},"reasoning_effort":{"type":"string","enum":["low","medium","high"]},"provider_options":{"type":"object","additionalProperties":false,"properties":{"openai":{"type":"object","additionalProperties":false,"properties":{"service_tier":{"type":"string","enum":["auto","default","flex","priority"]},"verbosity":{"type":"string","enum":["low","medium","high"]}}}}}}},"provider_endpoint_url":{"type":["string","null"],"format":"uri","maxLength":2000,"description":"Public HTTPS endpoint the organization default calls instead of the provider's standard API. `null` when there is no override."},"provider_endpoint_kind":{"type":"string","enum":["anthropic","openai","openai-compatible","anthropic_messages","openai_chat_completions","openai_responses","bedrock_converse","vertex_generate_content"],"description":"Wire protocol to speak to `provider_endpoint_url`. Read only when an endpoint URL is set. Stored NOT NULL, so it is switched rather than cleared: clearing an override means clearing the URL."},"resolved":{"type":"object","description":"What an inheriting agent resolves to today, reduced to non-secret fields. Carries `error` instead when resolution fails.","properties":{"connector":{"type":"string","description":"Connector slug, or `karta` for the Dharta platform connector."},"model_id":{"type":["string","null"]},"provider":{"type":["string","null"]},"credential_kind":{"type":"string","enum":["api_key","workload_identity"]},"error":{"type":"string","enum":["agent_builder_context_invalid","connector_adapter_canary_stale","connector_adapter_unavailable","connector_egress_forbidden","connector_endpoint_invalid","connector_execution_purpose_forbidden","connector_install_ineligible","connector_plan_forbidden","connector_principal_not_authorized","connector_verification_consent_required","connector_verification_not_approved","connector_verification_outcome_indeterminate","connector_verification_rate_limited","cutover_canary_authorization_invalid","model_auth_account_mismatch","model_auth_adapter_unavailable","model_auth_capability_disabled","model_auth_entitlement_exhausted","model_auth_expired","model_auth_funding_selection_required","model_auth_misconfigured","model_auth_missing","model_auth_new_session_required","model_auth_provider_unavailable","model_auth_reauthorization_required","model_auth_refresh_failed","model_auth_refresh_outcome_indeterminate","model_auth_revoked","model_auth_scope_ineligible","model_broker_budget_exhausted","model_broker_digest_key_unavailable","model_broker_lease_expired","model_broker_lease_stale","model_broker_relay_binding_mismatch","model_broker_required","model_broker_turn_deadline_exceeded","model_call_id_conflict","model_call_outcome_indeterminate","model_call_replay_expired","model_connector_concurrency_exceeded","model_connector_not_configured","model_connector_not_selected","model_connector_queue_timeout","model_connector_quota_scope_unavailable","model_default_not_configured","model_execution_context_mismatch","model_grant_expired","model_grant_invalid","model_grant_required","model_grant_revoked","model_identifier_digest_collision","model_not_exposed_by_selected_connector","model_not_exposed_by_selected_connectors","model_offer_unavailable","model_parameter_invalid","model_parameter_unsupported","model_policy_projection_mismatch","model_provider_endpoint_unavailable","model_provider_error","model_provider_protocol_error","model_provider_rate_limited","model_provider_redirected","model_provider_request_rejected","model_provider_unavailable","model_reference_invalid","model_resolution_unavailable","model_route_not_configured","model_route_unsupported","model_session_restart_required","model_surface_authority_invalid","model_target_not_supported","model_target_policy_forbidden","model_target_unavailable","source_model_binding_mismatch"]}}}}},"OrganizationModelSettingsResponse":{"type":"object","required":["model_settings"],"properties":{"model_settings":{"$ref":"#/components/schemas/OrganizationModelSettings"}}},"OrganizationModelSettingsUpdateRequest":{"type":"object","description":"Every key is optional. Only the keys you send change.","properties":{"connector_order":{"description":"Ordered connector slugs, most preferred first. `karta` names the Dharta platform connector. Accepts an array or one whitespace/comma-delimited string. `[]` means inherit.","oneOf":[{"type":"array","items":{"type":"string"}},{"type":"string"}]},"model_reference":{"description":"RFC 0070 model reference: `\"\"` for the connector default, `<model>`, `connector:<slug>/<model>`, or `route:<name>`. The typed mapping form is also accepted, and each kind carries exactly its own fields.","oneOf":[{"type":"string"},{"type":"object","title":"model reference","required":["kind","model"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["model"]},"model":{"type":"string"}}},{"type":"object","title":"target reference","required":["connector","kind","model"],"additionalProperties":false,"properties":{"connector":{"type":"string"},"kind":{"type":"string","enum":["target"]},"model":{"type":"string"}}},{"type":"object","title":"route reference","required":["kind","route"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["route"]},"route":{"type":"string"}}},{"type":"object","title":"default reference","required":["kind"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["default"]}}}]},"model_parameters":{"type":"object","additionalProperties":false,"description":"Patch, not a replacement: a null value clears that one key.","properties":{"temperature":{"type":["number","null"],"minimum":0,"maximum":2},"top_p":{"type":["number","null"],"exclusiveMinimum":0,"maximum":1},"max_output_tokens":{"type":["integer","null"],"minimum":1,"maximum":1000000},"reasoning_effort":{"type":["string","null"],"enum":["low","medium","high",null]},"provider_options":{"type":["object","null"],"additionalProperties":false,"properties":{"openai":{"type":"object","additionalProperties":false,"properties":{"service_tier":{"type":"string","enum":["auto","default","flex","priority"]},"verbosity":{"type":"string","enum":["low","medium","high"]}}}}}}},"provider_endpoint_url":{"type":["string","null"],"maxLength":2000,"description":"Public HTTPS endpoint the organization default calls instead of the provider's standard API. It must carry no credentials, query string, or fragment. Private, loopback, and link-local addresses are rejected, as is a subscription credential with an explicit endpoint. Send `\"\"` or `null` to clear the override; both mean the same thing."},"provider_endpoint_kind":{"type":"string","enum":["anthropic","openai","openai-compatible","anthropic_messages","openai_chat_completions","openai_responses","bedrock_converse","vertex_generate_content"],"description":"Wire protocol to speak to `provider_endpoint_url`. Read only when an endpoint URL is set. Stored NOT NULL, so it is switched rather than cleared: clearing an override means clearing the URL."}},"additionalProperties":false},"AgentModel":{"type":"object","required":["source","model_connection_id","parameters","connector_order","model_reference"],"properties":{"source":{"type":"string","enum":["inherit","platform","connection"],"description":"Which policy `connector_order` expresses. `inherit` is an empty order (the organization decides), `platform` selects the Dharta platform connector, `connection` selects one of this organization's own model connections."},"model_connection_id":{"type":["integer","null"],"description":"The selected model connection, non-null exactly when `source` is `connection`. Names the same selection as the first entry of `connector_order`."},"parameters":{"type":"object","additionalProperties":false,"properties":{"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","exclusiveMinimum":0,"maximum":1},"max_output_tokens":{"type":"integer","minimum":1,"maximum":1000000},"reasoning_effort":{"type":"string","enum":["low","medium","high"]},"provider_options":{"type":"object","additionalProperties":false,"properties":{"openai":{"type":"object","additionalProperties":false,"properties":{"service_tier":{"type":"string","enum":["auto","default","flex","priority"]},"verbosity":{"type":"string","enum":["low","medium","high"]}}}}}}},"connector_order":{"type":"array","items":{"type":"string"},"description":"Ordered connector slugs, most preferred first. `[]` means the agent inherits the organization policy."},"model_reference":{"type":"string","description":"Stored model reference in shorthand. `\"\"` means the connector default."}}},"AgentSettingsAgent":{"type":"object","required":["id","slug","name","deploy_enabled","serving_status","model"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"deploy_enabled":{"type":"boolean"},"serving_status":{"type":"string"},"dashboard_edits_enabled":{"type":"boolean"},"workspace_inspectable":{"type":"boolean"},"workspace_access":{"type":"object","additionalProperties":true},"durable_workspace_enabled":{"type":"boolean","description":"Whether this agent's kartas write to the durable store. A cost setting."},"deploy_branch":{"type":"string"},"archived_at":{"type":["string","null"],"format":"date-time"},"model":{"$ref":"#/components/schemas/AgentModel"}}},"ResolvedModel":{"type":"object","description":"What this agent resolves to today, reduced to non-secret fields. Carries `error` INSTEAD of the route when the organization cannot resolve a model, the same way organization model settings report it. The agent read still succeeds: reading an agent is not running it.","properties":{"error":{"type":"string","enum":["agent_builder_context_invalid","connector_adapter_canary_stale","connector_adapter_unavailable","connector_egress_forbidden","connector_endpoint_invalid","connector_execution_purpose_forbidden","connector_install_ineligible","connector_plan_forbidden","connector_principal_not_authorized","connector_verification_consent_required","connector_verification_not_approved","connector_verification_outcome_indeterminate","connector_verification_rate_limited","cutover_canary_authorization_invalid","model_auth_account_mismatch","model_auth_adapter_unavailable","model_auth_capability_disabled","model_auth_entitlement_exhausted","model_auth_expired","model_auth_funding_selection_required","model_auth_misconfigured","model_auth_missing","model_auth_new_session_required","model_auth_provider_unavailable","model_auth_reauthorization_required","model_auth_refresh_failed","model_auth_refresh_outcome_indeterminate","model_auth_revoked","model_auth_scope_ineligible","model_broker_budget_exhausted","model_broker_digest_key_unavailable","model_broker_lease_expired","model_broker_lease_stale","model_broker_relay_binding_mismatch","model_broker_required","model_broker_turn_deadline_exceeded","model_call_id_conflict","model_call_outcome_indeterminate","model_call_replay_expired","model_connector_concurrency_exceeded","model_connector_not_configured","model_connector_not_selected","model_connector_queue_timeout","model_connector_quota_scope_unavailable","model_default_not_configured","model_execution_context_mismatch","model_grant_expired","model_grant_invalid","model_grant_required","model_grant_revoked","model_identifier_digest_collision","model_not_exposed_by_selected_connector","model_not_exposed_by_selected_connectors","model_offer_unavailable","model_parameter_invalid","model_parameter_unsupported","model_policy_projection_mismatch","model_provider_endpoint_unavailable","model_provider_error","model_provider_protocol_error","model_provider_rate_limited","model_provider_redirected","model_provider_request_rejected","model_provider_unavailable","model_reference_invalid","model_resolution_unavailable","model_route_not_configured","model_route_unsupported","model_session_restart_required","model_surface_authority_invalid","model_target_not_supported","model_target_policy_forbidden","model_target_unavailable","source_model_binding_mismatch"],"description":"Present only when resolution failed, and then it is the only key."},"connector":{"type":["string","null"],"description":"Selected connector slug, or `karta` for the Dharta platform connector. Names the same selection as `model_connection_id`."},"model_connection_id":{"type":["integer","null"]},"model_id":{"type":["string","null"]},"provider":{"type":["string","null"]},"credential_kind":{"type":"string","enum":["api_key","workload_identity"]},"endpoint_url":{"type":["string","null"]},"api_format":{"type":["string","null"]},"custom_endpoint":{"type":"boolean"},"parameters":{"type":"object","additionalProperties":false,"properties":{"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","exclusiveMinimum":0,"maximum":1},"max_output_tokens":{"type":"integer","minimum":1,"maximum":1000000},"reasoning_effort":{"type":"string","enum":["low","medium","high"]},"provider_options":{"type":"object","additionalProperties":false,"properties":{"openai":{"type":"object","additionalProperties":false,"properties":{"service_tier":{"type":"string","enum":["auto","default","flex","priority"]},"verbosity":{"type":"string","enum":["low","medium","high"]}}}}}}}}},"AgentModelUpdateRequest":{"type":"object","description":"Every key is optional. Only the keys you send change.","additionalProperties":false,"properties":{"connector_order":{"description":"Ordered connector slugs, most preferred first. `karta` names the Dharta platform connector. Accepts an array or one whitespace/comma-delimited string. `[]` means inherit.","oneOf":[{"type":"array","items":{"type":"string"}},{"type":"string"}]},"model_reference":{"description":"RFC 0070 model reference: `\"\"` for the connector default, `<model>`, `connector:<slug>/<model>`, or `route:<name>`. The typed mapping form is also accepted, and each kind carries exactly its own fields.","oneOf":[{"type":"string"},{"type":"object","title":"model reference","required":["kind","model"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["model"]},"model":{"type":"string"}}},{"type":"object","title":"target reference","required":["connector","kind","model"],"additionalProperties":false,"properties":{"connector":{"type":"string"},"kind":{"type":"string","enum":["target"]},"model":{"type":"string"}}},{"type":"object","title":"route reference","required":["kind","route"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["route"]},"route":{"type":"string"}}},{"type":"object","title":"default reference","required":["kind"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["default"]}}}]},"model_parameters":{"type":"object","additionalProperties":false,"description":"Patch, not a replacement: a null value clears that one key.","properties":{"temperature":{"type":["number","null"],"minimum":0,"maximum":2},"top_p":{"type":["number","null"],"exclusiveMinimum":0,"maximum":1},"max_output_tokens":{"type":["integer","null"],"minimum":1,"maximum":1000000},"reasoning_effort":{"type":["string","null"],"enum":["low","medium","high",null]},"provider_options":{"type":["object","null"],"additionalProperties":false,"properties":{"openai":{"type":"object","additionalProperties":false,"properties":{"service_tier":{"type":"string","enum":["auto","default","flex","priority"]},"verbosity":{"type":"string","enum":["low","medium","high"]}}}}}}}}},"WebhookEndpoint":{"type":"object","required":["id","name","url","event_types","enabled","disabled_at","created_at","updated_at"],"properties":{"id":{"type":"integer"},"name":{"type":"string","maxLength":200},"url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"type":"string","enum":["api_key.created","api_key.revoked","subscription.created","subscription.updated","subscription.canceled","invoice.paid","invoice.payment_failed","organization.suspended","organization.resumed","usage.budget_threshold_reached","usage.budget_exhausted","session.started","turn.completed","turn.failed"]}},"enabled":{"type":"boolean"},"disabled_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Invitation":{"type":"object","required":["id","email","role","expires_at","created_at"],"properties":{"id":{"type":"integer"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["owner","admin","developer","billing","viewer"]},"expires_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"InvitationResponse":{"type":"object","required":["invitation"],"properties":{"invitation":{"$ref":"#/components/schemas/Invitation"}}},"AgentCreateRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name. The slug is derived from it when `slug` is absent. IGNORED when `github_repository_id` is present: that fork creates a source repo, not an agent, and the agent names itself from the `dharta.toml` the sync finds (the console's GitHub form has no name field for the same reason)."},"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,62}$"},"github_repository_id":{"type":"integer","description":"Link this installed GitHub repository as the source of truth instead of creating an empty hosted repo. The call then answers 202 with a `source_repo`, and the agent appears after the sync. `GET /api/github_repositories` lists the ids you may send."},"deploy_branch":{"type":"string","description":"Branch to deploy from. Only read with `github_repository_id`; the repository's default branch when absent."}}},"AgentLinkGithubResponse":{"type":"object","required":["source_repo","created"],"properties":{"source_repo":{"type":"object","required":["slug","deploy_branch","github_repository"],"properties":{"slug":{"type":"string"},"deploy_branch":{"type":"string"},"github_repository":{"type":"string","description":"owner/name on GitHub."},"clone_url":{"type":"string","format":"uri"}}},"created":{"type":"boolean","description":"False when this repository was already linked and is being re-synced."}}},"SyncNotQueuedResponse":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string","enum":["sync_not_queued"]},"message":{"type":"string"},"source_repo":{"type":"object","properties":{"slug":{"type":"string"},"deploy_branch":{"type":"string"},"github_repository":{"type":["string","null"]}}}}},"GithubRepositoryList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","full_name","default_branch","linked","installation"],"properties":{"id":{"type":"integer","description":"Send this as `github_repository_id`."},"full_name":{"type":"string","description":"owner/name on GitHub."},"default_branch":{"type":"string"},"linked":{"type":"boolean","description":"Already linked to a source repo in this organization."},"installation":{"type":"object","required":["account_login"],"properties":{"account_login":{"type":"string"},"account_type":{"type":["string","null"]}}}}}}}},"AgentCreateResponse":{"type":"object","required":["agent","clone_url","created"],"properties":{"agent":{"type":"object","required":["id","slug","name","deploy_branch"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"deploy_branch":{"type":"string"}}},"clone_url":{"type":"string","format":"uri","description":"Hosted git remote for `git push dharta main`."},"created":{"type":"boolean","description":"False when an agent with this slug already existed."}}},"Release":{"type":"object","required":["id","version","status","kind"],"properties":{"id":{"type":"integer"},"version":{"type":"integer"},"label":{"type":"string"},"status":{"type":"string"},"kind":{"type":"string"},"current":{"type":"boolean"},"activatable":{"type":"boolean"},"commit_sha":{"type":["string","null"]},"error_message":{"type":["string","null"]},"build_kind":{"type":["string","null"]},"pushed_via":{"type":["string","null"]},"harness_slug":{"type":["string","null"]},"harness_version":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"built_at":{"type":["string","null"],"format":"date-time"}}},"AgentRenameRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Display name."}}},"AgentToggleRequest":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}},"AgentFromTemplateRequest":{"type":"object","required":["template","name"],"properties":{"template":{"type":"string","description":"Template key from `GET /agent_templates`."},"name":{"type":"string","maxLength":100},"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,62}$","description":"Derived from `name` when absent."},"description":{"type":"string"},"harness":{"type":"string","description":"Harness slug, e.g. `claude-code`. Dharta's default when absent."},"harness_version":{"type":"string","description":"Requires `harness`. The harness default when absent."}}},"AgentFromTemplateResponse":{"type":"object","required":["agent","clone_url","created"],"properties":{"agent":{"$ref":"#/components/schemas/AgentSettingsAgent"},"clone_url":{"type":"string","format":"uri"},"created":{"type":"boolean"},"release":{"anyOf":[{"$ref":"#/components/schemas/Release"},{"type":"null"}]},"accepted":{"type":"boolean"},"phase":{"type":"string","description":"Present while release v1 is still building."},"state":{"type":"string","description":"Present while release v1 is still building."},"retryable":{"type":"boolean"}}},"ReleaseRetryResponse":{"type":"object","required":["agent","release","retried_release"],"properties":{"agent":{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"}}},"release":{"$ref":"#/components/schemas/Release"},"retried_release":{"$ref":"#/components/schemas/Release"},"message":{"type":"string"},"accepted":{"type":"boolean"},"phase":{"type":"string","description":"Present while the new release is building."},"state":{"type":"string","description":"Present while the new release is building."},"retryable":{"type":"boolean"}}},"AgentCodeUpdateRequest":{"type":"object","required":["files","base_version"],"properties":{"files":{"type":"object","additionalProperties":{"type":"string"},"description":"Edited files as { path => content }. Only the paths you send change. Every value must be a string; anything else is a 422."},"base_version":{"type":"integer","minimum":1,"description":"The release version the edits were made against, from `GET /api/agents/{slug}/releases`. Optimistic concurrency is always on: a save against any other version is a 409, never a clobber."}}},"AgentCodeUpdateResponse":{"type":"object","required":["version","status","changed","no_change","pending"],"properties":{"version":{"type":"integer"},"status":{"type":"string"},"changed":{"type":"array","items":{"type":"string"}},"no_change":{"type":"boolean"},"pending":{"type":"boolean"}}},"SourceRepoResponse":{"type":"object","required":["source_repo","clone_url","created"],"properties":{"source_repo":{"type":"object","required":["slug","deploy_branch"],"properties":{"slug":{"type":"string"},"deploy_branch":{"type":"string"}}},"clone_url":{"type":"string","format":"uri"},"created":{"type":"boolean"}}},"PublishResponse":{"type":"object","required":["accepted","agent","release"],"properties":{"accepted":{"type":"boolean"},"phase":{"type":"string","description":"Present while the release is still building."},"state":{"type":"string","description":"Present while the release is still building."},"retryable":{"type":"boolean"},"user_action":{"type":"string"},"agent":{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"}}},"release":{"type":"object","required":["version","status"],"properties":{"version":{"type":"integer"},"status":{"type":"string"},"harness_slug":{"type":["string","null"]},"harness_version":{"type":["string","null"]}}}}},"MintedToken":{"type":"object","required":["token","token_type","expires_in"],"properties":{"token":{"type":"string","description":"Bearer token. Shown once; it is not stored in readable form."},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer","description":"Seconds until the token expires."}}},"SessionTokenRequest":{"type":"object","properties":{"ttl_seconds":{"type":"integer","description":"Token lifetime. Defaults to the platform's session-token TTL."},"sub":{"type":"string","description":"The end user the calling backend already authenticated. Accepted as `sub` or `user_id`."},"user_id":{"type":"string","description":"Alias for `sub`."},"tenant_id":{"type":"string","format":"uuid","description":"Data-isolation tenant to bind the session to."},"self_scheduling":{"type":"boolean","description":"Let sessions on this token self-schedule one-shot wakeups for this agent. Live-mode keys only."}}},"WorkspaceTokenRequest":{"type":"object","required":["instance"],"properties":{"instance":{"type":"string","description":"The karta whose durable workspace the token reaches."},"scope":{"type":"string","enum":["git_read","workspace_read"],"default":"git_read","description":"The channel the token authorizes."}}},"SupportAccessTokenRequest":{"type":"object","properties":{"scope":{"type":"string","enum":["git_read","workspace_read"],"default":"git_read","description":"The channel the token authorizes. The grant must cover it."}}},"SourceRepoRequest":{"type":"object","properties":{"slug":{"type":"string","description":"Provision this repository directly, skipping agent selection."},"agent_slugs":{"type":"array","items":{"type":"string"},"description":"Candidate agents the push could land in."},"selected_agent_slug":{"type":"string","description":"Which candidate to use when several match."},"name":{"type":"string","description":"Repository name hint."}}},"ApiKeyCreateRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":200},"scopes":{"type":"array","minItems":1,"items":{"type":"string","enum":["agents:read","appearance:read","analytics:read","billing:read","caps:read","directories:read","embed_keys:read","env:read","instance_env:read","kartas:read","keys:read","members:read","model_connections:read","releases:read","schedules:read","sessions:read","source_repos:read","webhooks:read","fleet:read","agents:write","appearance:write","env:write","fleet:write","instance_env:write","kartas:write","organization:write","releases:write","schedules:write","embed_keys:write","caps:write","source_repos:write","env:secrets:read","source_archives:read","workspace_tokens:create","workspace:read","audit_log:export","fleet:subjects:read","members:invite","members:write","members:owner_role:write","agents:delete","keys:write","model_connections:write","fleet:subjects:write","organization:support_access:write","fleet:operations:write","webhooks:write"]}},"mode":{"type":"string","enum":["live","test"],"default":"live"},"expires_at":{"type":["string","null"],"format":"date-time"}}},"ApiKeyCreateResponse":{"type":"object","required":["api_key","secret"],"properties":{"api_key":{"$ref":"#/components/schemas/ApiKey"},"secret":{"type":"string","description":"Plaintext secret. Shown exactly once — store it now."}}},"ApiKeyRotateRequest":{"type":"object","properties":{"grace_period":{"type":"string","enum":["now","24h","7d"],"default":"24h","description":"How long the rotated key keeps working. `now` revokes it immediately."}}},"ApiKeyRotateResponse":{"type":"object","required":["api_key","secret","previous_key","grace_ends_at"],"properties":{"api_key":{"$ref":"#/components/schemas/ApiKey"},"secret":{"type":"string","description":"Plaintext secret. Shown exactly once - store it now."},"previous_key":{"$ref":"#/components/schemas/ApiKey"},"grace_ends_at":{"type":"string","format":"date-time"}}},"ApiKeyBulkUpdateRequest":{"type":"object","required":["action_name","ids"],"properties":{"action_name":{"type":"string","enum":["disable","enable","revoke"]},"ids":{"type":"array","minItems":1,"items":{"type":"integer"}}}},"ApiKeyBulkUpdateResponse":{"type":"object","required":["action","updated","skipped"],"properties":{"action":{"type":"string","enum":["disable","enable","revoke"]},"updated":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}},"skipped":{"type":"array","description":"Keys the action does not apply to, left unchanged.","items":{"$ref":"#/components/schemas/ApiKey"}}}},"ModelConnectionCreateRequest":{"type":"object","required":["provider","plaintext"],"properties":{"provider":{"type":"string","enum":["anthropic","openai","openrouter","xai","google"]},"plaintext":{"type":"string","description":"Provider API key plaintext. Encrypted at rest."},"name":{"type":"string","maxLength":200},"slug":{"type":"string","maxLength":63,"pattern":"^(?!\\d+$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$","description":"Organization-unique connector slug, a lowercase DNS label that is never only digits. Derived from `name` when you omit it."},"endpoint_url":{"type":"string","format":"uri"},"api_format":{"type":"string","enum":["anthropic_messages","openai_chat_completions","openai_responses"]}}},"ModelConnectionRotateRequest":{"type":"object","required":["plaintext"],"properties":{"plaintext":{"type":"string","description":"Replacement provider API key plaintext. Encrypted at rest."},"name":{"type":"string","maxLength":200,"description":"Renames the connection in the same audited write."}}},"ModelConnectionCreateResponse":{"type":"object","required":["model_connection"],"properties":{"model_connection":{"$ref":"#/components/schemas/ModelConnection"}}},"WebhookEndpointCreateRequest":{"type":"object","required":["url"],"properties":{"name":{"type":"string","maxLength":200},"url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"type":"string","enum":["api_key.created","api_key.revoked","subscription.created","subscription.updated","subscription.canceled","invoice.paid","invoice.payment_failed","organization.suspended","organization.resumed","usage.budget_threshold_reached","usage.budget_exhausted","session.started","turn.completed","turn.failed"]}}}},"WebhookEndpointCreateResponse":{"type":"object","required":["webhook_endpoint","secret"],"properties":{"webhook_endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"secret":{"type":"string","description":"HMAC signing secret. Shown exactly once."}}},"WebhookDeliveryResponse":{"type":"object","required":["delivery"],"properties":{"delivery":{"type":"object","required":["id","webhook_endpoint_id","event_id","event_type","created_at"],"properties":{"id":{"type":"integer"},"webhook_endpoint_id":{"type":"integer"},"event_id":{"type":"string","format":"uuid"},"event_type":{"type":"string"},"attempt":{"type":"integer"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}}}},"WebhookEndpointUpdateRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":200},"url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"type":"string","enum":["api_key.created","api_key.revoked","subscription.created","subscription.updated","subscription.canceled","invoice.paid","invoice.payment_failed","organization.suspended","organization.resumed","usage.budget_threshold_reached","usage.budget_exhausted","session.started","turn.completed","turn.failed"]},"description":"Replaces the subscription list. An empty array subscribes to every event."}}},"WebhookEndpointEnvelope":{"type":"object","required":["webhook_endpoint"],"properties":{"webhook_endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"UsageSummary":{"type":"object","required":["totals","budget"],"properties":{"totals":{"type":"object","properties":{"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"requests":{"type":"integer"}},"additionalProperties":{"type":"integer"}},"budget":{"type":["object","null"],"properties":{"monthly_cap_cents":{"type":["integer","null"]},"period_start":{"type":"string","format":"date-time"},"period_end":{"type":"string","format":"date-time"}}}}},"AnalyticsTrendPoint":{"type":"object","required":["date","value"],"properties":{"date":{"type":"string","format":"date"},"value":{"type":"integer"}}},"AnalyticsEntityResponse":{"type":"object","required":["view","range","from","to","series","summary","data"],"properties":{"view":{"type":"string","enum":["agents","users","instances","sessions","models"]},"range":{"type":"string","enum":["7d","30d","90d"]},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"series":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsTrendPoint"}},"summary":{"type":"object","additionalProperties":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"AnalyticsCostResponse":{"type":"object","required":["view","range","from","to","group_by","totals","series","data"],"properties":{"view":{"type":"string","enum":["cost"]},"range":{"type":"string","enum":["mtd","7d","30d","last_month","90d","custom"]},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"group_by":{"type":"string","enum":["agent","karta","session","user","model"]},"totals":{"type":"object","required":["tokens","token_cost_micros","platform_micros","total_micros"],"properties":{"tokens":{"type":"integer"},"token_cost_micros":{"type":"integer"},"platform_micros":{"type":"integer"},"total_micros":{"type":"integer"}}},"series":{"type":"array","items":{"type":"object","additionalProperties":true}},"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"DirectoryInstance":{"type":"object","required":["id","scoped_id","sessions_count","seats_count","tokens"],"properties":{"id":{"type":"string"},"scoped_id":{"type":"string"},"agent_slug":{"type":["string","null"]},"seats_count":{"type":"integer"},"sessions_count":{"type":"integer"},"last_at":{"type":["string","null"],"format":"date-time"},"tokens":{"type":"integer"},"cpu_seconds":{"type":["number","null"]},"disk_bytes":{"type":["integer","null"]},"spend_micros":{"type":"integer"},"cap_cents":{"type":["integer","null"]}}},"DirectoryEndUser":{"type":"object","required":["id","agents_count","kartas_count","sessions_count","tokens"],"properties":{"id":{"type":"string"},"agents_count":{"type":"integer"},"kartas_count":{"type":"integer"},"sessions_count":{"type":"integer"},"first_seen":{"type":["string","null"],"format":"date-time"},"last_seen":{"type":["string","null"],"format":"date-time"},"tokens":{"type":"integer"},"spend_micros":{"type":"integer"},"cap_cents":{"type":["integer","null"]}}},"DirectorySession":{"type":"object","required":["id","users_count","models_count","turns","input_tokens","output_tokens","tokens","cost_micros"],"properties":{"id":{"type":"string"},"agent_slug":{"type":["string","null"]},"karta_id":{"type":["string","null"]},"users_count":{"type":"integer"},"models_count":{"type":"integer"},"model":{"type":["string","null"]},"started_at":{"type":["string","null"],"format":"date-time"},"last_at":{"type":["string","null"],"format":"date-time"},"turns":{"type":"integer"},"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"tokens":{"type":"integer"},"cost_micros":{"type":"integer"}}},"KartaMember":{"type":"object","required":["id","email","role","joined_at"],"properties":{"id":{"type":"integer"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["viewer","participant","manager"]},"joined_at":{"type":"string","format":"date-time"}}},"KartaShare":{"type":"object","required":["id","prefix","name","agent_instance_id","created_at"],"properties":{"id":{"type":"integer"},"prefix":{"type":"string","description":"Visible prefix; the secret is shown only once."},"name":{"type":"string"},"agent_instance_id":{"type":"string","description":"The Dharta this link is pinned to."},"agent":{"type":["object","null"],"required":["id","slug","name"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"}}},"allowed_origins":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"}}},"Dharta":{"type":"object","required":["id","access_model","state"],"properties":{"id":{"type":"string","description":"Organization-scoped durable AgentInstance id."},"name":{"type":["string","null"],"maxLength":120},"vanity_slug":{"type":["string","null"],"maxLength":63},"access_audience":{"type":["string","null"],"enum":["members","anonymous",null]},"access_model":{"type":"string","enum":["trusted_binding","personal","native_shared"]},"state":{"type":"string","enum":["active","suspended","archived"]},"agent":{"type":["object","null"],"required":["id","slug","name"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"}}},"url":{"type":["string","null"],"format":"uri","description":"Stable hosted URL when the Dharta has a published identity."},"members":{"type":"array","description":"Active ACL memberships; present on detail and mutation responses.","items":{"$ref":"#/components/schemas/KartaMember"}}}},"AuditEvent":{"type":"object","required":["id","created_at","action","metadata"],"properties":{"id":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"action":{"type":"string"},"actor_email":{"type":["string","null"]},"api_key_prefix":{"type":["string","null"]},"subject_type":{"type":["string","null"]},"subject_id":{"type":["integer","null"]},"ip_address":{"type":["string","null"]},"user_agent":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":true}}},"SpendCap":{"type":"object","required":["id","cap_cents","created_at","updated_at"],"properties":{"id":{"type":"integer"},"cap_cents":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FleetCursorPage":{"type":"object","required":["next","previous"],"properties":{"next":{"type":["string","null"],"description":"Signed cursor for the next page."},"previous":{"type":["string","null"],"description":"Signed cursor for the previous page."},"per_page":{"type":"integer","minimum":1,"maximum":500}}},"EndUserProfile":{"type":"object","required":["external_subject_id","state","source","labels","groups","traits","agents_count","kartas_count","sessions_count","turns_count","tokens_count","cost_micros"],"properties":{"external_subject_id":{"type":"string","maxLength":255},"display_name":{"type":["string","null"],"maxLength":255},"email":{"type":["string","null"],"maxLength":255},"state":{"type":"string","enum":["active","suspended","archived"]},"source":{"type":"string","enum":["observed","api"]},"labels":{"type":"object","additionalProperties":{"type":"string"}},"groups":{"type":"array","items":{"type":"string"},"maxItems":50},"traits":{"type":"object","additionalProperties":true,"maxProperties":50},"first_seen_at":{"type":["string","null"],"format":"date-time"},"last_seen_at":{"type":["string","null"],"format":"date-time"},"agents_count":{"type":"integer","minimum":0},"kartas_count":{"type":"integer","minimum":0},"sessions_count":{"type":"integer","minimum":0},"turns_count":{"type":"integer","minimum":0},"tokens_count":{"type":"integer","minimum":0},"cost_micros":{"type":"integer","minimum":0}}},"EndUserProfileUpsertRequest":{"type":"object","required":["end_user_profile"],"properties":{"end_user_profile":{"type":"object","properties":{"display_name":{"type":["string","null"],"maxLength":255},"email":{"type":["string","null"],"maxLength":255},"state":{"type":"string","enum":["active","suspended","archived"]},"labels":{"type":"object","additionalProperties":{"type":"string"},"maxProperties":50},"groups":{"type":"array","items":{"type":"string"},"maxItems":50},"traits":{"type":"object","additionalProperties":true,"maxProperties":50}},"additionalProperties":false}},"additionalProperties":false},"FleetOperation":{"type":"object","required":["id","entity_type","action","status","targets","selection","created_at","parameters","dry_run_summary","warnings","requires_step_up"],"properties":{"id":{"type":"string","format":"uuid"},"entity_type":{"type":"string","enum":["agents","kartas","users","sessions"]},"action":{"type":"string","enum":["assign_owning_team","set_environment","set_lifecycle","set_label","clear_label","set_rollout_ring","pause_serving","resume_serving","redeploy","set_desired_release","rollback_release","set_model_policy","set_harness_policy","set_spend_cap","clear_spend_cap","suspend_karta","resume_karta","suspend_user","resume_user","set_user_label","clear_user_label","set_user_spend_cap","clear_user_spend_cap"],"description":"The change this operation applies to every target."},"status":{"type":"string","enum":["draft","queued","running","paused","completed","failed","cancelled","partially_completed"]},"parameters":{"type":"object","additionalProperties":true},"selection":{"type":"object","required":["mode","manifest_digest"],"properties":{"mode":{"type":"string","enum":["explicit","snapshot","all_matching"]},"manifest_digest":{"type":["string","null"],"description":"SHA-256 over the frozen target list. Identifies the exact set. Null only for an operation whose selection was never frozen."}}},"targets":{"type":"object","required":["total","pending","running","succeeded","failed","skipped","cancelled"],"properties":{"pending":{"type":"integer","minimum":0},"running":{"type":"integer","minimum":0},"succeeded":{"type":"integer","minimum":0},"failed":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0},"cancelled":{"type":"integer","minimum":0},"total":{"type":"integer","minimum":0}}},"dry_run_summary":{"type":"object","additionalProperties":true},"warnings":{"type":"array","items":{"type":"string"}},"requires_step_up":{"type":"boolean","description":"True when the console would demand a recent second factor before confirming. On this surface the bar is the fleet:operations:write scope instead."},"confirmation_phrase":{"type":["string","null"],"description":"Present only while the operation is a draft."},"last_error_code":{"type":["string","null"]},"last_error_message":{"type":["string","null"],"maxLength":500},"approved_at":{"type":["string","null"],"format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"cancel_requested_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"FleetOperationRequest":{"type":"object","required":["operation"],"properties":{"operation":{"type":"object","required":["action_key"],"properties":{"action_key":{"type":"string","enum":["assign_owning_team","set_environment","set_lifecycle","set_label","clear_label","set_rollout_ring","pause_serving","resume_serving","redeploy","set_desired_release","rollback_release","set_model_policy","set_harness_policy","set_spend_cap","clear_spend_cap","suspend_karta","resume_karta","suspend_user","resume_user","set_user_label","clear_user_label","set_user_spend_cap","clear_user_spend_cap"]},"entity_type":{"type":"string","enum":["agents","kartas","users","sessions"]},"selection_mode":{"type":"string","enum":["explicit","snapshot","all_matching"],"description":"`explicit` names ids directly; `snapshot` and `all_matching` freeze the rows a filter or saved view selects."},"saved_view_id":{"type":"string","format":"uuid"},"filter":{"type":"string","maxLength":2000},"explicit_ids":{"type":"array","items":{"type":"string"},"maxItems":10000},"parameters":{"type":"object","additionalProperties":false,"description":"The action's own parameters. `action_key` decides which of these apply; each action reads only the keys it defines and ignores the rest.","properties":{"team_slug":{"type":["string","null"]},"model_id":{"type":["string","null"]},"environment":{"type":"string"},"lifecycle":{"type":"string"},"label_assignment":{"type":"string"},"label_key":{"type":"string"},"rollout_ring":{"type":"string"},"harness_version":{"type":"string"},"release_version":{"type":["integer","string"]},"cap_cents":{"type":["integer","string"]}}}}}}},"FleetOperationConfirmRequest":{"type":"object","required":["confirmation_phrase"],"properties":{"confirmation_phrase":{"type":"string","description":"The phrase the preview returned, for example `APPLY 42 9F3B1C2D`."}}},"FleetRollout":{"type":"object","required":["id","name","status","target_release_version","current_partition_position","consecutive_unhealthy_windows","automatic_pause_enabled","automatic_rollback_enabled","anomaly_gate_enabled","shadow_mode","partitions","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120},"status":{"type":"string","enum":["draft","running","observing","paused","completed","failed","cancelled","rolled_back"]},"status_reason":{"type":["string","null"],"maxLength":500},"target_release_version":{"type":"integer","minimum":1},"rollback_release_version":{"type":["integer","null"],"minimum":1},"current_partition_position":{"type":"integer","minimum":0},"consecutive_unhealthy_windows":{"type":"integer","minimum":0},"automatic_pause_enabled":{"type":"boolean"},"automatic_rollback_enabled":{"type":"boolean"},"anomaly_gate_enabled":{"type":"boolean"},"shadow_mode":{"type":"boolean"},"started_at":{"type":["string","null"],"format":"date-time"},"paused_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"partitions":{"type":"array","items":{"$ref":"#/components/schemas/FleetRolloutPartition"}}}},"FleetRolloutPartition":{"type":"object","required":["position","name","percentage","target_count","status","observation_window_minutes","unhealthy_windows"],"properties":{"position":{"type":"integer","minimum":0},"name":{"type":"string"},"percentage":{"type":"integer","minimum":1,"maximum":100},"target_count":{"type":"integer","minimum":0},"status":{"type":"string","enum":["pending","running","observing","healthy","degraded","unknown","completed","paused","cancelled"]},"status_reason":{"type":["string","null"],"maxLength":500},"observation_window_minutes":{"type":"integer","minimum":0},"unhealthy_windows":{"type":"integer","minimum":0},"started_at":{"type":["string","null"],"format":"date-time"},"observing_at":{"type":["string","null"],"format":"date-time"},"next_evaluation_at":{"type":["string","null"],"format":"date-time"},"last_evaluated_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"FleetAnomalyFinding":{"type":"object","required":["id","metric","detector","status","classification","severity","title","detail","scope_definition","filter_digest","occurrence_count","observed_value","expected_low","expected_high","absolute_deviation","sample_count","confidence","materiality","complete","started_at","peak_at","detected_at","last_seen_at"],"description":"The detector's own evidence sample is deliberately not part of this shape: it references sessions and end users, which stay behind the fleet:subjects:read scope.","properties":{"id":{"type":"string","format":"uuid"},"metric":{"type":"string"},"detector":{"type":"string"},"status":{"type":"string","enum":["open","acknowledged","snoozed","resolved"]},"classification":{"type":"string","enum":["unclassified","expected","confirmed","muted"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"title":{"type":"string"},"detail":{"type":"string","maxLength":2000},"assigned_membership_id":{"type":["integer","null"]},"runbook_url":{"type":["string","null"],"maxLength":2000},"scope_definition":{"type":"object","additionalProperties":true},"filter_digest":{"type":"string"},"observed_value":{"type":"number"},"expected_low":{"type":"number"},"expected_high":{"type":"number"},"absolute_deviation":{"type":"number"},"relative_deviation":{"type":["number","null"]},"sample_count":{"type":"integer","minimum":0},"occurrence_count":{"type":"integer","minimum":1},"confidence":{"type":"number","minimum":0,"maximum":1},"materiality":{"type":"number"},"complete":{"type":"boolean"},"started_at":{"type":"string","format":"date-time"},"peak_at":{"type":"string","format":"date-time"},"detected_at":{"type":"string","format":"date-time"},"last_seen_at":{"type":"string","format":"date-time"},"recovery_at":{"type":["string","null"],"format":"date-time"},"resolved_at":{"type":["string","null"],"format":"date-time"},"snoozed_until":{"type":["string","null"],"format":"date-time"},"promoted_at":{"type":["string","null"],"format":"date-time"}}},"FleetFindingSnoozeRequest":{"type":"object","properties":{"duration":{"type":"string","enum":["1h","1d","1w"],"default":"1d"}}},"FleetFindingClassifyRequest":{"type":"object","required":["classification"],"properties":{"classification":{"type":"string","enum":["expected","confirmed","muted"]}}},"FleetFindingAssignRequest":{"type":"object","properties":{"membership_id":{"type":["integer","null"],"description":"Organization membership to assign. Omit or send null to unassign."}}},"FleetFindingRunbookRequest":{"type":"object","properties":{"runbook_url":{"type":["string","null"],"maxLength":2000,"description":"An http(s) URL, or null or \"\" to clear the link."}}},"FleetSavedView":{"type":"object","required":["id","url","entity_type","name","visibility","organization_default","definition_version","definition","favorite","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"entity_type":{"type":"string","enum":["agents","kartas","users","sessions","analytics"]},"name":{"type":"string","maxLength":100},"description":{"type":["string","null"],"maxLength":2000},"visibility":{"type":"string","enum":["private","team","organization"]},"team_id":{"type":["integer","null"]},"owner_membership_id":{"type":["integer","null"]},"organization_default":{"type":"boolean"},"definition_version":{"type":"integer","minimum":1},"definition":{"type":"object","additionalProperties":true},"favorite":{"type":"boolean","description":"Whether the membership behind this API key has pinned the view."},"updated_at":{"type":"string","format":"date-time"}}},"FleetSavedViewRequest":{"type":"object","required":["saved_view"],"properties":{"saved_view":{"type":"object","properties":{"entity_type":{"type":"string","enum":["agents","kartas","users","sessions","analytics"]},"name":{"type":"string","maxLength":100},"description":{"type":["string","null"],"maxLength":2000},"visibility":{"type":"string","enum":["private","team","organization"]},"organization_team_id":{"type":["integer","null"]},"organization_default":{"type":"boolean","description":"Requires organization visibility and an owner or admin creator."},"definition":{"type":"object","additionalProperties":true,"description":"Filter, columns, sort, grouping, density, time, comparison and chart. At most 32 KB."}}}}},"FleetAnalyticsSaveRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":100},"description":{"type":["string","null"],"maxLength":2000},"metric":{"type":"string","default":"turns"},"range":{"type":"string","description":"A relative window such as `30d`, or `custom`."},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"scope_kind":{"type":"string"},"scope_ids":{"type":"string","description":"Comma-separated scope identifiers."},"bucket":{"type":"string"},"aggregation":{"type":"string"},"comparison":{"type":"string"},"comparison_saved_view":{"type":"string","format":"uuid","description":"Required when `comparison` is `saved_scope`."},"breakdown":{"type":"array","items":{"type":"string"},"maxItems":2},"events":{"type":"array","items":{"type":"string"},"maxItems":20},"filters":{"type":"object","additionalProperties":true}}},"FleetExportRequest":{"type":"object","required":["export"],"properties":{"export":{"type":"object","required":["entity_type","explicit_ids"],"properties":{"entity_type":{"type":"string","enum":["agents","kartas","users","sessions"]},"explicit_ids":{"type":"array","items":{"type":"string"},"maxItems":10000,"description":"Internal row identifiers, as the catalog returns them."}}}}},"EnvVar":{"type":"object","required":["name","secret"],"properties":{"name":{"type":"string"},"secret":{"type":"boolean"},"value":{"type":"string","description":"Absent for secret-marked values on list, and on pull without include_secrets."},"withheld":{"type":"boolean","description":"Pull only: true when the value was excluded (secret without include_secrets)."},"updated_at":{"type":"string","format":"date-time"}}},"BillingStatus":{"type":"object","required":["plan_key"],"properties":{"plan_key":{"type":"string","description":"Identifier of the active plan (e.g. `free`, `pro`)."},"stripe_configured":{"type":"boolean"},"subscription_state":{"type":["string","null"],"description":"`active`, `past_due`, `canceled`, …"},"current_period_end":{"type":["string","null"],"format":"date-time"}}}},"responses":{"IdempotencyKeyTooLong":{"description":"Idempotency-Key is longer than 255 characters (`idempotency_key_too_long`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"IdempotencyInProgress":{"description":"A request with this Idempotency-Key is still executing (`idempotency_in_progress`). Retry it; the stored response replays once the first request finishes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"IdempotencyKeyReused":{"description":"This Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`). The first response is never disclosed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"security":[{"bearerAuth":[]},{"cookieAuth":[]}],"x-dharta-capabilities":[{"capability":"agents.list","method":"GET","path":"/api/agents","executionModes":["public_api","curated_cli"],"requiredScopes":["agents:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"agents.show","method":"GET","path":"/api/agents/{slug}","executionModes":["public_api","curated_cli"],"requiredScopes":["agents:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"agents.invocations","method":"GET","path":"/api/agents/{slug}/invocations","executionModes":["public_api","curated_cli"],"requiredScopes":["agents:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"agents.logs","method":"GET","path":"/api/agents/{slug}/logs","executionModes":["public_api","curated_cli"],"requiredScopes":["agents:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"agents.create","method":"POST","path":"/api/agents","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#create"]},{"capability":"agents.rename","method":"PATCH","path":"/api/agents/{slug}/name","executionModes":["public_api","curated_cli","console","copilot_proposable"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#update_name"]},{"capability":"agents.durable_workspace.update","method":"PATCH","path":"/api/agents/{slug}/durable_workspace","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#update_durable_workspace"]},{"capability":"agents.create_from_template","method":"POST","path":"/api/agents/from_template","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#create_from_template"]},{"capability":"agents.deploy","method":"POST","path":"/api/agents/{slug}/deploy","executionModes":["public_api","curated_cli","console"],"requiredScopes":["releases:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#deploy"]},{"capability":"agents.code.update","method":"PUT","path":"/api/agents/{slug}/code","executionModes":["public_api","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agent_code#update"]},{"capability":"agents.serving.update","method":"PATCH","path":"/api/agents/{slug}/serving","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#update_serving"]},{"capability":"agents.dashboard_edits.update","method":"PATCH","path":"/api/agents/{slug}/dashboard_edits","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#update_dashboard_edits"]},{"capability":"agents.model.update","method":"PATCH","path":"/api/agents/{slug}/model","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#update_model"]},{"capability":"agents.workspace_inspectable.update","method":"PATCH","path":"/api/agents/{slug}/workspace_inspectable","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write","workspace_tokens:create"],"scopeMatch":"all","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"workspace_tokens:create is a forced-expiry scope (90 days), and the row demands it together with agents:write, so a key that can flip workspace inspection was minted deliberately behind a browser step-up and expires on its own.","consoleTwin":true,"consoleActions":["agents#update_workspace_inspectable"]},{"capability":"agents.workspace_access.update","method":"PATCH","path":"/api/agents/{slug}/workspace_access","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write","workspace_tokens:create"],"scopeMatch":"all","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"Same forced-expiry pair as the master flip: workspace_tokens:create plus agents:write, both required, so the grant matrix cannot be changed by a long-lived routine key.","consoleTwin":true,"consoleActions":["agents#update_workspace_access"]},{"capability":"agents.delete","method":"DELETE","path":"/api/agents/{slug}","executionModes":["public_api","curated_cli","console","copilot_proposable"],"requiredScopes":["agents:delete"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"agents:delete is a tenant-administration scope with forced 90-day expiry, and the delete is a reversible soft-archive that `agents.show` still lists, so a bounded durable scope carries the same weight as the console's step-up-if-enrolled prompt.","consoleTwin":true,"consoleActions":["agents#destroy"]},{"capability":"analytics.agents","method":"GET","path":"/api/analytics/agents","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"analytics.users","method":"GET","path":"/api/analytics/users","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"analytics.instances","method":"GET","path":"/api/analytics/instances","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"analytics.sessions","method":"GET","path":"/api/analytics/sessions","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"analytics.models","method":"GET","path":"/api/analytics/models","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"analytics.cost","method":"GET","path":"/api/analytics/cost","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"api_keys.list","method":"GET","path":"/api_keys","executionModes":["public_api","curated_cli"],"requiredScopes":["keys:read","keys:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"api_keys.create","method":"POST","path":"/api_keys","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#create"]},{"capability":"api_keys.rename","method":"PATCH","path":"/api_keys/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#update"]},{"capability":"api_keys.revoke","method":"DELETE","path":"/api_keys/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#destroy"]},{"capability":"api_keys.rotate","method":"POST","path":"/api_keys/{id}/rotate","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#rotate"]},{"capability":"api_keys.disable","method":"POST","path":"/api_keys/{id}/disable","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#disable"]},{"capability":"api_keys.enable","method":"POST","path":"/api_keys/{id}/enable","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#enable"]},{"capability":"api_keys.bulk_update","method":"POST","path":"/api_keys/bulk_update","executionModes":["public_api","curated_cli","console"],"requiredScopes":["keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"keys:write is a tenant-administration scope with forced 90-day expiry. Minting one requires a browser step-up, so the assurance the console demands per action is paid once at mint. The expiry is a rotation cadence, not a bound on that assurance: the same key can mint or rotate for another 90 days without a second step-up, which is the authority api_keys.create already carries.","consoleTwin":true,"consoleActions":["api_keys#bulk_update"]},{"capability":"appearance.get","method":"GET","path":"/api/agents/{slug}/appearance","executionModes":["public_api","curated_cli"],"requiredScopes":["appearance:read","appearance:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"appearance.update","method":"PATCH","path":"/api/agents/{slug}/appearance","executionModes":["public_api","curated_cli","console"],"requiredScopes":["appearance:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agents#update_appearance"]},{"capability":"audit_events.export","method":"GET","path":"/api/audit_events","executionModes":["public_api","curated_cli","console"],"requiredScopes":["audit_log:export"],"scopeMatch":"any","idempotent":false,"assurance":"recent_step_up","assuranceWhen":"csv_export?","headlessAssurance":"audit_log:export is a sensitive scope with forced 90-day expiry, so the key that can pull the log was minted behind a browser step-up and cannot outlive it. Every pull records an audit_log.exported event naming the key.","consoleTwin":true,"consoleActions":["audit_events#index"]},{"capability":"billing.status","method":"GET","path":"/api/billing","executionModes":["public_api","curated_cli"],"requiredScopes":["billing:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"caps.budget.show","method":"GET","path":"/api/limits/budget","executionModes":["public_api","curated_cli"],"requiredScopes":["caps:read","caps:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"caps.budget.update","method":"PATCH","path":"/api/limits/budget","executionModes":["public_api","curated_cli","console"],"requiredScopes":["caps:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["limits#update_budget"]},{"capability":"caps.instance.show","method":"GET","path":"/api/limits/instances/{id}/cap","executionModes":["public_api","curated_cli"],"requiredScopes":["caps:read","caps:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"caps.instance.update","method":"PATCH","path":"/api/limits/instances/{id}/cap","executionModes":["public_api","curated_cli","console"],"requiredScopes":["caps:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#update_cap"]},{"capability":"caps.end_user.show","method":"GET","path":"/api/limits/end_users/{id}/cap","executionModes":["public_api","curated_cli"],"requiredScopes":["caps:read","caps:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"caps.end_user.update","method":"PATCH","path":"/api/limits/end_users/{id}/cap","executionModes":["public_api","curated_cli","console"],"requiredScopes":["caps:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["end_users#update_cap"]},{"capability":"caps.seat.show","method":"GET","path":"/api/limits/instances/{id}/seat_cap","executionModes":["public_api","curated_cli"],"requiredScopes":["caps:read","caps:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"caps.seat.update","method":"PATCH","path":"/api/limits/instances/{id}/seat_cap","executionModes":["public_api","curated_cli","console"],"requiredScopes":["caps:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#update_seat_cap"]},{"capability":"directories.instances","method":"GET","path":"/api/agents/{slug}/directories/instances","executionModes":["public_api","curated_cli"],"requiredScopes":["directories:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"directories.end_users","method":"GET","path":"/api/agents/{slug}/directories/end_users","executionModes":["public_api","curated_cli"],"requiredScopes":["directories:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"directories.sessions","method":"GET","path":"/api/agents/{slug}/directories/sessions","executionModes":["public_api","curated_cli"],"requiredScopes":["directories:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"embed_keys.list","method":"GET","path":"/api/agents/{slug}/embed_keys","executionModes":["public_api","curated_cli"],"requiredScopes":["embed_keys:read","embed_keys:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"embed_keys.create","method":"POST","path":"/api/agents/{slug}/embed_keys","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#create"]},{"capability":"embed_keys.update","method":"PATCH","path":"/api/agents/{slug}/embed_keys/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#update"]},{"capability":"embed_keys.rotate","method":"POST","path":"/api/agents/{slug}/embed_keys/{id}/rotate","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#rotate"]},{"capability":"embed_keys.disable","method":"POST","path":"/api/agents/{slug}/embed_keys/{id}/disable","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#disable"]},{"capability":"embed_keys.enable","method":"POST","path":"/api/agents/{slug}/embed_keys/{id}/enable","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#enable"]},{"capability":"embed_keys.identity.set","method":"POST","path":"/api/agents/{slug}/embed_keys/{id}/identity","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#update"]},{"capability":"embed_keys.identity.clear","method":"DELETE","path":"/api/agents/{slug}/embed_keys/{id}/identity","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#update"]},{"capability":"embed_keys.revoke","method":"DELETE","path":"/api/agents/{slug}/embed_keys/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["embed_keys:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["embed_keys#destroy"]},{"capability":"env.list","method":"GET","path":"/api/agents/{slug}/env","executionModes":["public_api","curated_cli"],"requiredScopes":["env:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"env.pull","method":"POST","path":"/api/agents/{slug}/env/pull","executionModes":["public_api","curated_cli"],"requiredScopes":["env:read"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"env.pull_secrets","method":"POST","path":"/api/agents/{slug}/env/pull","executionModes":["public_api","curated_cli"],"requiredScopes":["env:secrets:read"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"env.update","method":"PUT","path":"/api/agents/{slug}/env/{name}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["env:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agent_env_vars#create"]},{"capability":"env.delete","method":"DELETE","path":"/api/agents/{slug}/env/{name}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["env:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["agent_env_vars#destroy"]},{"capability":"fleet.catalog","method":"GET","path":"/api/fleet/{entity_type}","executionModes":["public_api"],"requiredScopes":["fleet:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"fleet.subject_catalog","method":"GET","path":"/api/fleet/{entity_type}","executionModes":["public_api"],"requiredScopes":["fleet:subjects:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"fleet.end_user_profiles.list","method":"GET","path":"/api/end_user_profiles","executionModes":["public_api"],"requiredScopes":["fleet:subjects:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"fleet.end_user_profiles.show","method":"GET","path":"/api/end_user_profiles/{id}","executionModes":["public_api"],"requiredScopes":["fleet:subjects:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"fleet.end_user_profiles.upsert","method":"PUT","path":"/api/end_user_profiles/{id}","executionModes":["public_api"],"requiredScopes":["fleet:subjects:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"fleet.operations.create","method":"POST","path":"/api/fleet/operations","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/operations#create"]},{"capability":"fleet.operations.confirm","method":"POST","path":"/api/fleet/operations/{id}/confirm","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":"operation_requires_step_up?","headlessAssurance":"fleet:operations:write, a TENANT_ADMIN scope with a forced 90-day expiry, granted separately from fleet:write and revocable without touching it","consoleTwin":true,"consoleActions":["fleet/operations#confirm"]},{"capability":"fleet.operations.cancel","method":"POST","path":"/api/fleet/operations/{id}/cancel","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":"operation_requires_step_up?","headlessAssurance":"fleet:operations:write, a TENANT_ADMIN scope with a forced 90-day expiry, granted separately from fleet:write and revocable without touching it","consoleTwin":true,"consoleActions":["fleet/operations#cancel"]},{"capability":"fleet.operations.retry","method":"POST","path":"/api/fleet/operations/{id}/retry","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":"operation_requires_step_up?","headlessAssurance":"fleet:operations:write, a TENANT_ADMIN scope with a forced 90-day expiry, granted separately from fleet:write and revocable without touching it","consoleTwin":true,"consoleActions":["fleet/operations#retry"]},{"capability":"fleet.rollouts.advance","method":"POST","path":"/api/fleet/rollouts/{id}/advance","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"fleet:operations:write, a TENANT_ADMIN scope with a forced 90-day expiry, granted separately from fleet:write and revocable without touching it","consoleTwin":true,"consoleActions":["fleet/rollouts#advance"]},{"capability":"fleet.rollouts.pause","method":"POST","path":"/api/fleet/rollouts/{id}/pause","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/rollouts#pause"]},{"capability":"fleet.rollouts.resume","method":"POST","path":"/api/fleet/rollouts/{id}/resume","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/rollouts#resume"]},{"capability":"fleet.rollouts.evaluate","method":"POST","path":"/api/fleet/rollouts/{id}/evaluate","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/rollouts#evaluate"]},{"capability":"fleet.rollouts.rollback","method":"POST","path":"/api/fleet/rollouts/{id}/rollback","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:operations:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"fleet:operations:write, a TENANT_ADMIN scope with a forced 90-day expiry, granted separately from fleet:write and revocable without touching it","consoleTwin":true,"consoleActions":["fleet/rollouts#rollback"]},{"capability":"fleet.findings.acknowledge","method":"POST","path":"/api/fleet/findings/{id}/acknowledge","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#acknowledge"]},{"capability":"fleet.findings.snooze","method":"POST","path":"/api/fleet/findings/{id}/snooze","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#snooze"]},{"capability":"fleet.findings.resolve","method":"POST","path":"/api/fleet/findings/{id}/resolve","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#resolve"]},{"capability":"fleet.findings.reopen","method":"POST","path":"/api/fleet/findings/{id}/reopen","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#reopen"]},{"capability":"fleet.findings.classify","method":"POST","path":"/api/fleet/findings/{id}/classify","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#classify"]},{"capability":"fleet.findings.assign","method":"POST","path":"/api/fleet/findings/{id}/assign","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#assign"]},{"capability":"fleet.findings.promote","method":"POST","path":"/api/fleet/findings/{id}/promote","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#promote"]},{"capability":"fleet.findings.update","method":"PATCH","path":"/api/fleet/findings/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/findings#update"]},{"capability":"fleet.saved_views.create","method":"POST","path":"/api/fleet/saved_views","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/saved_views#create"]},{"capability":"fleet.saved_views.update","method":"PATCH","path":"/api/fleet/saved_views/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/saved_views#update"]},{"capability":"fleet.saved_views.delete","method":"DELETE","path":"/api/fleet/saved_views/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/saved_views#destroy"]},{"capability":"fleet.saved_views.favorite","method":"POST","path":"/api/fleet/saved_views/{id}/favorite","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/saved_views#favorite"]},{"capability":"fleet.saved_views.unfavorite","method":"DELETE","path":"/api/fleet/saved_views/{id}/favorite","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/saved_views#unfavorite"]},{"capability":"fleet.analytics.save","method":"POST","path":"/api/fleet/analytics/saved_views","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/analytics#save"]},{"capability":"fleet.analytics.unpin","method":"DELETE","path":"/api/fleet/analytics/saved_views/{id}/pin","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/analytics#unpin"]},{"capability":"fleet.exports.create","method":"POST","path":"/api/fleet/exports","executionModes":["public_api","curated_cli","console"],"requiredScopes":["fleet:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["fleet/exports#create"]},{"capability":"instance_env.list","method":"GET","path":"/api/agents/{agent_slug}/instances/{agent_instance_id}/env","executionModes":["public_api","curated_cli"],"requiredScopes":["instance_env:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"instance_env.update","method":"PUT","path":"/api/agents/{agent_slug}/instances/{agent_instance_id}/env/{name}","executionModes":["public_api","curated_cli"],"requiredScopes":["instance_env:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"instance_env.delete","method":"DELETE","path":"/api/agents/{agent_slug}/instances/{agent_instance_id}/env/{name}","executionModes":["public_api","curated_cli"],"requiredScopes":["instance_env:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"instructions.get","method":"GET","path":"/api/agents/{slug}/instructions","executionModes":["public_api","curated_cli"],"requiredScopes":["agents:read","agents:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"instructions.update","method":"PUT","path":"/api/agents/{slug}/instructions","executionModes":["public_api","curated_cli","console"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["claude_mds#update"]},{"capability":"kartas.list","method":"GET","path":"/api/kartas","executionModes":["public_api","curated_cli"],"requiredScopes":["kartas:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"kartas.show","method":"GET","path":"/api/kartas/{id}","executionModes":["public_api","curated_cli"],"requiredScopes":["kartas:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"kartas.create","method":"POST","path":"/api/kartas","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#create"]},{"capability":"kartas.update","method":"PATCH","path":"/api/kartas/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#update_identity_access","agents#name_karta"]},{"capability":"kartas.grant_member","method":"POST","path":"/api/kartas/{id}/members","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#add_member"]},{"capability":"kartas.update_member","method":"PATCH","path":"/api/kartas/{id}/members/{membership_id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#update_member"]},{"capability":"kartas.revoke_member","method":"DELETE","path":"/api/kartas/{id}/members/{membership_id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#remove_member"]},{"capability":"kartas.archive","method":"DELETE","path":"/api/kartas/{id}","executionModes":["public_api","curated_cli"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"kartas.restore","method":"POST","path":"/api/kartas/{id}/restore","executionModes":["public_api","curated_cli"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"kartas.share.create","method":"POST","path":"/api/kartas/{id}/share","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#create_share"]},{"capability":"kartas.share.revoke","method":"DELETE","path":"/api/kartas/{id}/shares/{share_id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["kartas:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["instances#destroy_share"]},{"capability":"marketplace_support_access.create","method":"POST","path":"/api/marketplace/support_grants/{id}/workspace_tokens","executionModes":["public_api","curated_cli"],"requiredScopes":["workspace_tokens:create"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"members.list","method":"GET","path":"/api/members","executionModes":["public_api","curated_cli"],"requiredScopes":["members:read","members:invite","members:write","members:owner_role:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"members.invite","method":"POST","path":"/api/members/invitations","executionModes":["public_api","curated_cli","console"],"requiredScopes":["members:invite"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"members:* are tenant-administration scopes with forced 90-day expiry, and the target-dependent rules (owner-role escalation, self-demotion) are evaluated against the minting user's membership, so the key cannot exceed the human who created it.","consoleTwin":true,"consoleActions":["settings/member_invitations#create"]},{"capability":"members.update_role","method":"PATCH","path":"/api/members/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["members:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"members:* are tenant-administration scopes with forced 90-day expiry, and the target-dependent rules (owner-role escalation, self-demotion) are evaluated against the minting user's membership, so the key cannot exceed the human who created it.","consoleTwin":true,"consoleActions":["settings/members#update"]},{"capability":"members.remove","method":"DELETE","path":"/api/members/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["members:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"members:* are tenant-administration scopes with forced 90-day expiry, and the target-dependent rules (owner-role escalation, self-demotion) are evaluated against the minting user's membership, so the key cannot exceed the human who created it.","consoleTwin":true,"consoleActions":["settings/members#destroy"]},{"capability":"members.invitation_revoke","method":"DELETE","path":"/api/members/invitations/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["members:invite"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"members:* are tenant-administration scopes with forced 90-day expiry, and the target-dependent rules (owner-role escalation, self-demotion) are evaluated against the minting user's membership, so the key cannot exceed the human who created it.","consoleTwin":true,"consoleActions":["settings/member_invitations#destroy"]},{"capability":"members.invitation_resend","method":"POST","path":"/api/members/invitations/{id}/resend","executionModes":["public_api","curated_cli","console"],"requiredScopes":["members:invite"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"members:* are tenant-administration scopes with forced 90-day expiry, and the target-dependent rules (owner-role escalation, self-demotion) are evaluated against the minting user's membership, so the key cannot exceed the human who created it.","consoleTwin":true,"consoleActions":["settings/member_invitations#resend"]},{"capability":"model_connections.list","method":"GET","path":"/model_connections","executionModes":["public_api","curated_cli"],"requiredScopes":["model_connections:read","model_connections:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"model_connections.create","method":"POST","path":"/model_connections","executionModes":["public_api","curated_cli","console"],"requiredScopes":["model_connections:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"model_connections:write is a tenant-administration scope with forced 90-day expiry, so a key that can store or revoke a provider credential was minted behind a browser step-up and expires on its own. Stored plaintext is never readable back over the API.","consoleTwin":true,"consoleActions":["model_connections#create"]},{"capability":"model_connections.revoke","method":"DELETE","path":"/model_connections/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["model_connections:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"model_connections:write is a tenant-administration scope with forced 90-day expiry, so a key that can store or revoke a provider credential was minted behind a browser step-up and expires on its own. Stored plaintext is never readable back over the API.","consoleTwin":true,"consoleActions":["model_connections#destroy"]},{"capability":"model_connections.rotate","method":"PATCH","path":"/model_connections/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["model_connections:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"model_connections:write is a tenant-administration scope with forced 90-day expiry, so a key that can store or revoke a provider credential was minted behind a browser step-up and expires on its own. Stored plaintext is never readable back over the API.","consoleTwin":true,"consoleActions":["model_connections#update"]},{"capability":"model_connections.models.list","method":"GET","path":"/model_connections/{id}/models","executionModes":["public_api","curated_cli"],"requiredScopes":["model_connections:read","model_connections:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"model_connections.models.configure","method":"PUT","path":"/model_connections/{id}/models","executionModes":["public_api","curated_cli","console"],"requiredScopes":["model_connections:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"model_connections:write is a tenant-administration scope with forced 90-day expiry, so a key that can choose which connector and which model serve a turn was minted behind a browser step-up and expires on its own. Neither route reads or returns credential material.","consoleTwin":true,"consoleActions":["model_connections#update_models"]},{"capability":"organization.model_settings.show","method":"GET","path":"/api/organization/model_settings","executionModes":["public_api","curated_cli"],"requiredScopes":["model_connections:read","model_connections:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"organization.model_settings.update","method":"PATCH","path":"/api/organization/model_settings","executionModes":["public_api","curated_cli","console"],"requiredScopes":["model_connections:write"],"scopeMatch":"any","idempotent":true,"assurance":"mfa_enrolled","assuranceWhen":null,"headlessAssurance":"model_connections:write is a tenant-administration scope with forced 90-day expiry, so a key that can choose which connector and which model serve a turn was minted behind a browser step-up and expires on its own. Neither route reads or returns credential material.","consoleTwin":true,"consoleActions":["model_connections#update_default"]},{"capability":"organization.rename","method":"PATCH","path":"/api/organization","executionModes":["public_api","curated_cli","console"],"requiredScopes":["organization:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["settings/organizations#update"]},{"capability":"organization.support_access.update","method":"PATCH","path":"/api/organization/support_access","executionModes":["public_api","curated_cli","console"],"requiredScopes":["organization:support_access:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"organization:support_access:write, a tenant-administration scope with forced 90-day expiry, AND the key's creator must be a current owner of the organization. A key therefore cannot reach a setting its minter could not.","consoleTwin":true,"consoleActions":["settings/support_access#update"]},{"capability":"organization.transcript_access.update","method":"PATCH","path":"/api/organization/support_access/transcripts","executionModes":["public_api","curated_cli","console"],"requiredScopes":["organization:support_access:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"organization:support_access:write, a tenant-administration scope with forced 90-day expiry, AND the key's creator must be a current owner of the organization. A key therefore cannot reach a setting its minter could not.","consoleTwin":true,"consoleActions":["settings/support_access#update_transcript_access"]},{"capability":"publishes.create","method":"POST","path":"/api/agents/{slug}/publish","executionModes":["public_api","curated_cli"],"requiredScopes":["releases:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"releases.list","method":"GET","path":"/api/agents/{slug}/releases","executionModes":["public_api","curated_cli"],"requiredScopes":["releases:read","releases:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"releases.activate","method":"POST","path":"/api/agents/{slug}/releases/{version}/activate","executionModes":["public_api","curated_cli","console","copilot_proposable"],"requiredScopes":["releases:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["releases#activate"]},{"capability":"releases.retry","method":"POST","path":"/api/agents/{slug}/releases/{version}/retry","executionModes":["public_api","curated_cli","console"],"requiredScopes":["releases:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["releases#retry"]},{"capability":"releases.rollback","method":"POST","path":"/api/agents/{slug}/rollback","executionModes":["public_api","curated_cli"],"requiredScopes":["releases:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"releases.archive","method":"GET","path":"/api/agents/{slug}/releases/{version}/archive","executionModes":["public_api","curated_cli"],"requiredScopes":["source_archives:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"schedules.list","method":"GET","path":"/api/agents/{slug}/schedules","executionModes":["public_api","curated_cli"],"requiredScopes":["schedules:read","schedules:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"schedules.create","method":"POST","path":"/api/agents/{slug}/schedules","executionModes":["public_api","curated_cli","console"],"requiredScopes":["schedules:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["schedules#create"]},{"capability":"schedules.delete","method":"DELETE","path":"/api/agents/{slug}/schedules/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["schedules:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["schedules#destroy"]},{"capability":"schedules.pause","method":"POST","path":"/api/agents/{slug}/schedules/{id}/pause","executionModes":["public_api","curated_cli","console"],"requiredScopes":["schedules:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["schedules#pause"]},{"capability":"schedules.resume","method":"POST","path":"/api/agents/{slug}/schedules/{id}/resume","executionModes":["public_api","curated_cli","console"],"requiredScopes":["schedules:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["schedules#resume"]},{"capability":"schedules.run","method":"POST","path":"/api/agents/{slug}/schedules/{id}/run","executionModes":["public_api","curated_cli","console"],"requiredScopes":["schedules:write"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":true,"consoleActions":["schedules#run_now"]},{"capability":"session_tokens.create","method":"POST","path":"/api/agents/{slug}/session_tokens","executionModes":["public_api","curated_cli"],"requiredScopes":["agents:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"source_repos.create","method":"POST","path":"/api/source_repos","executionModes":["public_api","curated_cli"],"requiredScopes":["source_repos:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"github_repositories.list","method":"GET","path":"/api/github_repositories","executionModes":["public_api","curated_cli"],"requiredScopes":["source_repos:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"source_repos.disconnect_github","method":"DELETE","path":"/api/source_repos/{slug}/github","executionModes":["public_api","curated_cli","console"],"requiredScopes":["source_repos:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"source_repos:write, a routine durable scope, AND the key's creator must be a current owner or admin. The scope alone would not do: it is the scope hosted-git CI is told to use, so a build key would be able to sever delivery. The creator bar is the console's admin-only gate carried over, read per request so a departed minter takes it with them. The scope stays routine rather than forced-expiry because the disconnect removes a deploy path rather than widening access: current releases stay live, no data becomes readable, the binding can be restored through the GitHub App install flow, and every disconnect is audited.","consoleTwin":true,"consoleActions":["source_repos#disconnect_github"]},{"capability":"usage.summary","method":"GET","path":"/api/usage","executionModes":["public_api","curated_cli"],"requiredScopes":["analytics:read"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"webhook_endpoints.list","method":"GET","path":"/api/webhook_endpoints","executionModes":["public_api","curated_cli"],"requiredScopes":["webhooks:read","webhooks:write"],"scopeMatch":"any","idempotent":false,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]},{"capability":"webhook_endpoints.create","method":"POST","path":"/api/webhook_endpoints","executionModes":["public_api","curated_cli","console"],"requiredScopes":["webhooks:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"webhooks:write is a tenant-administration scope with forced 90-day expiry. A webhook destination is an egress trust root: any URL is accepted, and an empty event list subscribes to every event, so a new endpoint can start billing, API-key, session and turn data flowing to a host the caller chooses. Every change records an audit event.","consoleTwin":true,"consoleActions":["webhook_endpoints#create"]},{"capability":"webhook_endpoints.update","method":"PATCH","path":"/api/webhook_endpoints/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["webhooks:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"webhooks:write is a tenant-administration scope with forced 90-day expiry. A webhook destination is an egress trust root: any URL is accepted, and an empty event list subscribes to every event, so a new endpoint can start billing, API-key, session and turn data flowing to a host the caller chooses. Every change records an audit event.","consoleTwin":true,"consoleActions":["webhook_endpoints#update"]},{"capability":"webhook_endpoints.enable","method":"POST","path":"/api/webhook_endpoints/{id}/enable","executionModes":["public_api","curated_cli","console"],"requiredScopes":["webhooks:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"webhooks:write is a tenant-administration scope with forced 90-day expiry. A webhook destination is an egress trust root: any URL is accepted, and an empty event list subscribes to every event, so a new endpoint can start billing, API-key, session and turn data flowing to a host the caller chooses. Every change records an audit event.","consoleTwin":true,"consoleActions":["webhook_endpoints#update"]},{"capability":"webhook_endpoints.test","method":"POST","path":"/api/webhook_endpoints/{id}/test","executionModes":["public_api","curated_cli","console"],"requiredScopes":["webhooks:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"webhooks:write is a tenant-administration scope with forced 90-day expiry. A webhook destination is an egress trust root: any URL is accepted, and an empty event list subscribes to every event, so a new endpoint can start billing, API-key, session and turn data flowing to a host the caller chooses. Every change records an audit event.","consoleTwin":true,"consoleActions":["webhook_endpoints#test"]},{"capability":"webhook_endpoints.delete","method":"DELETE","path":"/api/webhook_endpoints/{id}","executionModes":["public_api","curated_cli","console"],"requiredScopes":["webhooks:write"],"scopeMatch":"any","idempotent":true,"assurance":"recent_step_up","assuranceWhen":null,"headlessAssurance":"webhooks:write is a tenant-administration scope with forced 90-day expiry. A webhook destination is an egress trust root: any URL is accepted, and an empty event list subscribes to every event, so a new endpoint can start billing, API-key, session and turn data flowing to a host the caller chooses. Every change records an audit event.","consoleTwin":true,"consoleActions":["webhook_endpoints#destroy"]},{"capability":"workspace_tokens.create","method":"POST","path":"/api/agents/{slug}/workspace_tokens","executionModes":["public_api","curated_cli"],"requiredScopes":["workspace_tokens:create"],"scopeMatch":"any","idempotent":true,"assurance":"none","assuranceWhen":null,"headlessAssurance":null,"consoleTwin":false,"consoleActions":[]}],"x-dharta-browser-only":[{"capability":"billing.checkout","reason":"Stripe-hosted payment ceremony. There is no headless equivalent to hand a card to.","consoleActions":["billing#checkout"],"deepLink":"/billing","assurance":"mfa_enrolled","assuranceWhen":null},{"capability":"billing.portal","reason":"Opens a Stripe-hosted customer portal session bound to the signed-in browser.","consoleActions":["billing#portal"],"deepLink":"/billing","assurance":"mfa_enrolled","assuranceWhen":null},{"capability":"billing.buy_pack","reason":"Buying credits is a Stripe checkout ceremony; a credential must not be able to spend money.","consoleActions":["billing#buy_pack"],"deepLink":"/billing","assurance":"mfa_enrolled","assuranceWhen":null},{"capability":"billing.auto_refill","reason":"Standing authority to charge a card. A human sets it, in a browser, behind step-up.","consoleActions":["billing#auto_refill"],"deepLink":"/billing","assurance":"mfa_enrolled","assuranceWhen":null},{"capability":"identity.mfa_enroll","reason":"Second-factor enrollment is the trust root a credential is derived from. Minting a key that could enroll one would invert the dependency.","consoleActions":["account/security#setup","account/security#create_confirmation"],"deepLink":"/account/security","assurance":"none","assuranceWhen":null},{"capability":"identity.mfa_disable","reason":"Removing the second factor lowers the bar every other action is measured against.","consoleActions":["account/security#destroy"],"deepLink":"/account/security","assurance":"recent_step_up","assuranceWhen":null},{"capability":"identity.recovery_codes","reason":"Regenerating recovery codes is a one-time reveal of account-recovery secrets.","consoleActions":["account/security#regenerate_recovery_codes"],"deepLink":"/account/security","assurance":"recent_step_up","assuranceWhen":null},{"capability":"identity.webauthn_credentials","reason":"WebAuthn registration and removal are browser-bound ceremonies; the authenticator signs a challenge the browser issued.","consoleActions":["account/credentials#create","account/credentials#destroy"],"deepLink":"/account/security","assurance":"none","assuranceWhen":null},{"capability":"identity.step_up","reason":"The step-up prompt IS the browser ceremony. Exposing it headlessly would mint the elevation it exists to gate.","consoleActions":["account/step_up#create","account/step_up#webauthn_verify"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"identity.oauth_unlink","reason":"Unlinking a sign-in provider changes how the account authenticates.","consoleActions":["account/connected_accounts#destroy"],"deepLink":"/account/security","assurance":"none","assuranceWhen":null},{"capability":"organization.transfer_ownership","reason":"Ownership transfer is a trust root: it is the one action that can strip the actor of the authority to undo it.","consoleActions":["settings/members#transfer_ownership"],"deepLink":"/settings/members","assurance":"mfa_enrolled","assuranceWhen":null},{"capability":"organization.leave","reason":"Self-removal ends the human membership a key inherits its target-dependent rules from.","consoleActions":["settings/members#leave"],"deepLink":"/settings/members","assurance":"recent_step_up","assuranceWhen":null},{"capability":"cli_authorization.approve","reason":"Approving a device grant from a credential would defeat the grant: the browser approval is what proves a human, not a token, asked for the new token.","consoleActions":["cli_authorizations#show","cli_authorizations#create"],"deepLink":null,"assurance":"mfa_enrolled","assuranceWhen":null},{"capability":"copilot.proposal_approve","reason":"The copilot's threat model is agent proposes, human approves. A credential-executed approval removes the human half of it.","consoleActions":["account/proposals#approve"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"copilot.proposal_cancel","reason":"Cancelling is the other half of the same human decision, and must not be reachable by the agent that proposed it.","consoleActions":["account/proposals#cancel"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"organization.create","reason":"A key is minted within one organization and has no authority to create another. Creating one is an account-lifecycle action for the signed-in human.","consoleActions":["organizations#create"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"organization.accept_invitation","reason":"Accepting an invitation binds a signed-in human to an organization; there is no key principal on either side of it yet.","consoleActions":["organization_invitations#accept"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"closed_beta.invite","reason":"A referral invite spends the signed-in user's personal allocation, not org authority.","consoleActions":["closed_beta_invitations#create"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"dashboard.switch_organization","reason":"Session-scoped UI state: it moves the browser session between organizations. A key already names its organization.","consoleActions":["dashboard#switch"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"dashboard.test_mode_toggle","reason":"Session-scoped UI state. The headless equivalent is presenting a dh_test_ key, which carries the mode on the credential itself.","consoleActions":["test_mode#toggle"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"wallet.top_up","reason":"Buying credit is a Stripe checkout ceremony, and a credential must not be able to spend money. Same position as billing.buy_pack, for the consumer wallet.","consoleActions":["account/wallet#top_up"],"deepLink":"/account/wallet","assurance":"none","assuranceWhen":null},{"capability":"marketplace.trial_start","reason":"A trial is Dharta's own money, granted once per human per Agent, and the bound on it is the signed-in Devise session that proves the human (RFC 0080 §18.8). A credential that could start trials is an account-farming tool.","consoleActions":["consumer/trials#create"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"marketplace.subscribe","reason":"It opens Stripe Checkout and hands a card to Stripe's own page. There is no headless equivalent, and a credential must not be able to start a recurring charge on a person's account. Same position as billing.checkout, for the consumer door.","consoleActions":["consumer/subscriptions#create"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"marketplace.buyer_licence","reason":"Ending or restarting one's own licence is a consumer commerce decision on a personal account. A key is minted inside an organization, and a consumer holds none.","consoleActions":["account/kartas#cancel","account/kartas#resume","account/subscriptions#cancel","account/subscriptions#resume"],"deepLink":"/account","assurance":"none","assuranceWhen":null},{"capability":"marketplace.buyer_export","reason":"It mints a read-only workspace clone token. The headless equivalent already exists and is separately scoped - workspace_tokens.create, gated on workspace:read - so a second door to the same bytes would be one without that scope.","consoleActions":["account/kartas#export"],"deepLink":"/account","assurance":"none","assuranceWhen":null},{"capability":"marketplace.close_account","reason":"Closing an account is irreversible, ends every subscription and starts the clock on erasing every karta (RFC 0090 C26). It is gated on a step-up plus a typed email confirmation, both of which are browser ceremonies; a headless equivalent would be a credential that can delete the account holding it. privacy@ requests run through `marketplace:close_consumer_account`, which is audited to a named operator.","consoleActions":["account/closures#create"],"deepLink":"/account/close","assurance":"none","assuranceWhen":null},{"capability":"marketplace.support_grants","reason":"A support grant hands a publisher a read of the buyer's private karta for a bounded window (RFC 0084 D3). Only the buyer can issue or revoke it, and a consumer holds no credential that could stand in for that decision.","consoleActions":["account/support_grants#create","account/support_grants#destroy"],"deepLink":"/account","assurance":"none","assuranceWhen":null},{"capability":"marketplace.buyer_review","reason":"A verified review is a named human's public statement about a purchase they made (RFC 0080 §11.3). The signed-in session is what ties it to the buyer, and a credential that could write reviews is a review-farming tool - the exact attack §18.9 names.","consoleActions":["account/reviews#create","account/reviews#update"],"deepLink":"/account","assurance":"none","assuranceWhen":null},{"capability":"marketplace.listing_report","reason":"Reporting a listing opens a trust-and-safety queue item against a named seller. It is signed-in on purpose (the anonymous intake is /abuse), and a scriptable report endpoint is a way to bury a competitor's listing in the queue.","consoleActions":["consumer/listing_reports#create"],"deepLink":null,"assurance":"none","assuranceWhen":null},{"capability":"marketplace.review_response","reason":"The publisher's public reply under a buyer's words. One response, editable, and it is a piece of writing rather than an operation - the same position as listing content.","consoleActions":["settings/marketplace/reviews#respond"],"deepLink":"/settings/marketplace","assurance":"none","assuranceWhen":null},{"capability":"marketplace.karta_updates","reason":"RFC 0080 §9.3: approving an update is the buyer's consent to a manifest that asks for more than they already agreed to, and RFC 0084 D5 gives that consent to the manager alone. A credential that could grant it would remove the human the rule exists to protect. Choosing the update policy is the same decision, made ahead of time.","consoleActions":["account/karta_updates#approve","account/karta_updates#policy"],"deepLink":"/account","assurance":"none","assuranceWhen":null},{"capability":"marketplace.publisher_onboarding","reason":"Accepting the marketplace agreement is a named human's signature on a contract, and the payout account is a Stripe-hosted onboarding ceremony bound to this browser.","consoleActions":["settings/marketplace#accept_terms","settings/marketplace#create"],"deepLink":"/settings/marketplace","assurance":"none","assuranceWhen":null},{"capability":"marketplace.listing_authoring","reason":"The listing is the claim Dharta's review stands behind and the description a buyer accepts at checkout. Submitting it asks for a human verdict on a human's assertion, and delisting is terminal for that Agent's place in the marketplace.","consoleActions":["settings/marketplace/listings#create","settings/marketplace/listings#submit","settings/marketplace/listings#return_to_draft","settings/marketplace/listings#delist","settings/marketplace/listings#request_public","settings/marketplace/listings#appeal","settings/marketplace/listing_revisions#create","settings/marketplace/listing_revisions#update"],"deepLink":"/settings/marketplace","assurance":"none","assuranceWhen":null},{"capability":"marketplace.listing_domain","reason":"Pointing a domain at Dharta decides where this listing's page appears and under whose name, so claiming or removing one is the owner's act - the same commitment as putting the listing on sale. The DNS records it asks for are typed into a registrar by the person who controls the domain, and there is nothing here for a credential to do.","consoleActions":["settings/marketplace/listing_domains#create","settings/marketplace/listing_domains#verify","settings/marketplace/listing_domains#destroy"],"deepLink":"/settings/marketplace","assurance":"none","assuranceWhen":null},{"capability":"marketplace.offer_terms","reason":"Publishing terms is what puts a price in front of strangers, and published terms never mutate again (RFC 0080 DA3). A mis-scripted price is not correctable in place.","consoleActions":["settings/marketplace/offers#create","settings/marketplace/offers#activate","settings/marketplace/offers#withdraw","settings/marketplace/offer_revisions#create","settings/marketplace/offer_revisions#update","settings/marketplace/offer_revisions#publish"],"deepLink":"/settings/marketplace","assurance":"none","assuranceWhen":null},{"capability":"marketplace.listing_media","reason":"The cover image and the drafted copy are claims on the page a buyer reads, so they belong to the same human authoring ceremony as the listing text. Generating either also SPENDS the organisation's own provider credential (RFC 0090 C34), and a control-plane API key must not be able to run up a bill on a model account it was never issued for.","consoleActions":["settings/marketplace/listing_hero_images#create","settings/marketplace/listing_hero_images#update","settings/marketplace/listing_hero_images#destroy","settings/marketplace/listing_copy_drafts#create"],"deepLink":"/settings/marketplace","assurance":"none","assuranceWhen":null},{"capability":"model_subscriptions.manage","reason":"A personal provider subscription belongs to the signed-in human. An organization API key cannot authorize provider login, logout, revocation, or choose another user's connection.","consoleActions":["user_model_connections#create","user_model_connections#logout","user_model_connections#destroy"],"deepLink":"/user_model_connections","assurance":"none","assuranceWhen":null},{"capability":"model_settings.preview_default","reason":"A read rendered as a sentence for the operator about to save. The data behind it is already headless as `resolved` on GET /api/organization/model_settings, so a bearer twin would restate one read in prose.","consoleActions":["model_connections#preview_default"],"deepLink":"/model_connections","assurance":"none","assuranceWhen":null}],"paths":{"/me":{"get":{"summary":"Identify the calling API key","operationId":"whoami","tags":["auth"],"description":"Returns the organization and key metadata for the presented bearer token. Backs `dharta auth status`.","responses":{"200":{"description":"The calling key and its organization.","content":{"application/json":{"schema":{"type":"object","required":["organization","api_key"],"properties":{"organization":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"api_key":{"type":"object","required":["name","prefix","scopes","created_at","expires_at"],"properties":{"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"}}}}}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agent_templates":{"get":{"summary":"List agent templates","operationId":"listAgentTemplates","tags":["templates"],"description":"The template set behind `dharta init` and the dashboard's new-agent page. Anonymous; the CLI bundles the same files as offline fallback.","security":[],"responses":{"200":{"description":"Available templates with their full file trees.","content":{"application/json":{"schema":{"type":"object","required":["templates"],"properties":{"templates":{"type":"array","items":{"type":"object","required":["key","title","description","files"],"properties":{"key":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"files":{"type":"object","additionalProperties":{"type":"string"}}}}}}}}}}}}},"/cli/device_authorizations":{"post":{"summary":"Start a CLI device-flow login","operationId":"createDeviceAuthorization","tags":["auth"],"description":"RFC 8628 device authorization. Unauthenticated; rate-limited per IP. The CLI shows `user_code`, opens `verification_uri`, then polls the token endpoint.","security":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"client_name":{"type":"string","description":"Hostname shown on the approve page and used in the minted key's name."}}}}}},"responses":{"201":{"description":"Device authorization created.","content":{"application/json":{"schema":{"type":"object","required":["device_code","user_code","verification_uri","expires_in","interval"],"properties":{"device_code":{"type":"string"},"user_code":{"type":"string"},"verification_uri":{"type":"string"},"verification_uri_complete":{"type":"string"},"expires_in":{"type":"integer"},"interval":{"type":"integer"}}}}}}}}},"/cli/device_authorizations/token":{"post":{"summary":"Poll a device-flow login for its token","operationId":"pollDeviceAuthorization","tags":["auth"],"description":"RFC 8628 token poll. Returns 400 with `authorization_pending`, `slow_down`, `expired_token`, `access_denied`, or `invalid_grant` until approval; then a one-time 200 with the minted key.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["device_code"],"properties":{"device_code":{"type":"string"}}}}}},"responses":{"200":{"description":"Approved and claimed (one-time response).","content":{"application/json":{"schema":{"type":"object","required":["access_token","token_type"],"properties":{"access_token":{"type":"string"},"token_type":{"type":"string"},"scope":{"type":"string"}}}}}},"400":{"description":"Not (yet) grantable; see `error` code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/audit_events":{"get":{"summary":"Export audit events as JSON","operationId":"exportAuditEvents","tags":["audit"],"parameters":[{"name":"event_action","in":"query","required":false,"schema":{"type":"string"}},{"name":"user_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Audit event rows.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"meta":{"type":"object","required":["row_estimate","limit"],"properties":{"row_estimate":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"403":{"description":"Caller lacks audit_log:export scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/audit_events.csv":{"get":{"summary":"Export audit events as CSV","operationId":"exportAuditEventsCsv","tags":["audit"],"parameters":[{"name":"event_action","in":"query","required":false,"schema":{"type":"string"}},{"name":"user_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Audit event CSV export.","content":{"text/csv":{"schema":{"type":"string"}}}},"403":{"description":"Caller lacks audit_log:export scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fleet/{entity_type}":{"get":{"summary":"Query a durable fleet catalog","operationId":"queryFleetCatalog","tags":["fleet"],"description":"Returns a bounded, cursor-paginated organization inventory. Users and sessions require the separate expiring `fleet:subjects:read` scope; agents and kartas require `fleet:read`.","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","enum":["agents","kartas","users","sessions"]}},{"name":"filter","in":"query","required":false,"schema":{"type":"string","maxLength":2000}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}},{"name":"facets","in":"query","required":false,"description":"Comma-separated allowlisted facet keys.","schema":{"type":"string"}},{"name":"columns","in":"query","required":false,"description":"Comma-separated projection groups.","schema":{"type":"string"}}],"responses":{"200":{"description":"Fleet catalog page.","content":{"application/json":{"schema":{"type":"object","required":["data","page","facets"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"page":{"$ref":"#/components/schemas/FleetCursorPage"},"facets":{"type":"object","additionalProperties":true}}}}}},"403":{"description":"Caller lacks the required fleet scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid filter, projection, sort, or cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/end_user_profiles":{"get":{"summary":"List managed external-user profiles","operationId":"listEndUserProfiles","tags":["fleet"],"description":"PII-bearing inventory. Requires an expiring `fleet:subjects:read` API key.","parameters":[{"name":"filter","in":"query","required":false,"schema":{"type":"string","maxLength":2000}},{"name":"after","in":"query","required":false,"schema":{"type":"string"}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Managed end-user profile page.","content":{"application/json":{"schema":{"type":"object","required":["data","page"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EndUserProfile"}},"page":{"$ref":"#/components/schemas/FleetCursorPage"}}}}}},"403":{"description":"Caller lacks fleet:subjects:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid filter or cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/end_user_profiles/{id}":{"get":{"summary":"Show a managed external-user profile","operationId":"showEndUserProfile","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Managed end-user profile.","content":{"application/json":{"schema":{"type":"object","required":["end_user_profile"],"properties":{"end_user_profile":{"$ref":"#/components/schemas/EndUserProfile"}}}}}},"403":{"description":"Caller lacks fleet:subjects:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Profile is not in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Provision or update a managed external-user profile","operationId":"upsertEndUserProfile","tags":["fleet"],"description":"Requires an expiring `fleet:subjects:write` API key. Trait keys must be approved in the organization's indexed-trait allowlist.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndUserProfileUpsertRequest"}}}},"responses":{"200":{"description":"Provisioned or updated profile.","content":{"application/json":{"schema":{"type":"object","required":["end_user_profile"],"properties":{"end_user_profile":{"$ref":"#/components/schemas/EndUserProfile"}}}}}},"403":{"description":"Caller lacks fleet:subjects:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid lifecycle state or metadata. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/kartas":{"get":{"summary":"List Kartas","operationId":"listKartas","tags":["kartas"],"description":"Lists durable Dharta identities for the calling organization. Archived Kartas are excluded by default. Requires `kartas:read` scope.","parameters":[{"name":"agent","in":"query","required":false,"description":"Limit results to one owning agent slug.","schema":{"type":"string"}},{"name":"named","in":"query","required":false,"description":"When true, return only Kartas with both a name and vanity slug.","schema":{"type":"boolean"}},{"name":"archived","in":"query","required":false,"description":"When true, return ONLY archived Kartas (the default listing excludes them), so an archived Dharta can be found and restored.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Kartas for the calling organization.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Dharta"}}}}}}},"403":{"description":"Caller lacks kartas:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a native shared Dharta","operationId":"createKarta","tags":["kartas"],"description":"Creates one durable team Dharta with a stable identity, creator-manager, and optional initial member ACL. Requires the `kartas:write` scope. Send an Idempotency-Key header to make retries safe.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent","name","vanity_slug"],"properties":{"agent":{"type":"string","description":"Owning agent slug."},"name":{"type":"string","minLength":1,"maxLength":120},"vanity_slug":{"type":"string","maxLength":63,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$"},"access_audience":{"type":["string","null"],"enum":["members","anonymous",null],"default":"members"},"members":{"type":"array","items":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["viewer","participant","manager"],"default":"participant"}}}}}}}}},"responses":{"201":{"description":"Created native shared Dharta and active ACL.","content":{"application/json":{"schema":{"type":"object","required":["karta"],"properties":{"karta":{"$ref":"#/components/schemas/Dharta"}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown agent or organization user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid identity, audience, or member role. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/kartas/{id}":{"get":{"summary":"Show a Dharta","operationId":"showKarta","tags":["kartas"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Dharta identity and active ACL.","content":{"application/json":{"schema":{"type":"object","required":["karta"],"properties":{"karta":{"$ref":"#/components/schemas/Dharta"}}}}}},"403":{"description":"Caller lacks kartas:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta id in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Configure a Dharta identity and audience","operationId":"updateKarta","tags":["kartas"],"description":"Publishes or updates the stable hosted identity. Requires the `kartas:write` scope. Send an Idempotency-Key header to make retries safe.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"vanity_slug":{"type":"string","maxLength":63,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$"},"access_audience":{"type":"string","enum":["members","anonymous"]}}}}}},"responses":{"200":{"description":"Updated Dharta identity and ACL.","content":{"application/json":{"schema":{"type":"object","required":["karta"],"properties":{"karta":{"$ref":"#/components/schemas/Dharta"}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta id in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid identity or audience. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Archive a Dharta","operationId":"archiveKarta","tags":["kartas"],"description":"Retires the Dharta: a REVERSIBLE archive, not a delete. The durable workspace and its history are kept - restore returns them whole - and the Dharta drops out of the default list. Erasing the underlying tree is a separate administrative operation. Archiving an already-archived Dharta is a no-op. Requires the `kartas:write` scope. Send an Idempotency-Key header to make retries safe.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Archived Dharta.","content":{"application/json":{"schema":{"type":"object","required":["karta"],"properties":{"karta":{"$ref":"#/components/schemas/Dharta"}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta id in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/kartas/{id}/restore":{"post":{"summary":"Restore an archived Dharta","operationId":"restoreKarta","tags":["kartas"],"description":"Returns an archived Dharta to service with its durable workspace and history intact. Restoring a Dharta that is not archived is a no-op. Requires the `kartas:write` scope. Send an Idempotency-Key header to make retries safe.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Restored Dharta.","content":{"application/json":{"schema":{"type":"object","required":["karta"],"properties":{"karta":{"$ref":"#/components/schemas/Dharta"}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta id in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/kartas/{id}/members":{"post":{"summary":"Grant Dharta access","operationId":"grantKartaMember","tags":["kartas"],"description":"Adds or restores an organization user in the Dharta ACL. Requires the `kartas:write` scope. Send an Idempotency-Key header to make retries safe.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["viewer","participant","manager"],"default":"participant"}}}}}},"responses":{"201":{"description":"Granted membership.","content":{"application/json":{"schema":{"type":"object","required":["member"],"properties":{"member":{"$ref":"#/components/schemas/KartaMember"}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta or organization user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid membership. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/kartas/{id}/members/{membership_id}":{"patch":{"summary":"Change a Dharta member role","operationId":"updateKartaMember","tags":["kartas"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"membership_id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["viewer","participant","manager"]}}}}}},"responses":{"200":{"description":"Updated membership.","content":{"application/json":{"schema":{"type":"object","required":["member"],"properties":{"member":{"$ref":"#/components/schemas/KartaMember"}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta or active membership.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid role or last-manager protection. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Revoke Dharta access","operationId":"revokeKartaMember","tags":["kartas"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"membership_id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Membership revoked."},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown Dharta or active membership.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Last-manager protection prevented revocation. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/kartas/{id}/share":{"post":{"summary":"Create a no-sign-in share link","operationId":"createKartaShare","tags":["kartas"],"description":"Mints an origin-fenced publishable key pinned to this karta, so anyone with the link gets their own session against the same durable workspace and spends from its budget. The secret and the full link are returned ONCE and are never readable again. Refused for a members-only karta, which uses its stable URL and member list instead, and for a karta no agent has run yet. Requires `kartas:write` scope and an Idempotency-Key header.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Created share link, with its one-time secret.","content":{"application/json":{"schema":{"type":"object","required":["share","secret","url"],"properties":{"share":{"$ref":"#/components/schemas/KartaShare"},"secret":{"type":"string","description":"Publishable key, shown once."},"url":{"type":"string","format":"uri","description":"The link to hand out."}}}}}},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown karta id in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Members-only karta, no owning agent, or invalid key. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/kartas/{id}/shares/{share_id}":{"delete":{"summary":"Revoke a no-sign-in share link","operationId":"revokeKartaShare","tags":["kartas"],"description":"Withdraws one share link. Revoking an already-revoked link is a no-op. Requires `kartas:write` scope and an Idempotency-Key header.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"share_id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Share link revoked."},"403":{"description":"Caller lacks kartas:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown share link for this karta.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents":{"get":{"summary":"List agents","operationId":"listAgents","tags":["agents"],"description":"Backs `dharta agent list`. Requires `agents:read` scope.","responses":{"200":{"description":"Agents for the calling organization.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","slug","name","deploy_branch"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"deploy_branch":{"type":"string"},"current_version":{"type":["integer","null"]},"current_status":{"type":["string","null"]},"archived_at":{"type":["string","null"],"format":"date-time"}}}}}}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller lacks agents:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create an agent","operationId":"createAgent","tags":["agents"],"description":"Backs `dharta create`. Idempotent by construction: creating an agent whose slug already exists returns it unchanged with `created: false`. Requires `agents:write` scope.\n\nSend `github_repository_id` to link an installed GitHub repository as the source of truth instead. That fork answers 202 and creates a source repo, not an agent: the agent appears once the sync finds a single enabled `dharta.toml` on the deploy branch, so poll `GET /api/agents` for it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateRequest"}}}},"responses":{"201":{"description":"The agent was created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateResponse"}}}},"200":{"description":"An agent with this slug already existed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateResponse"}}}},"202":{"description":"The GitHub repository is linked and its sync is queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentLinkGithubResponse"}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller lacks agents:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`github_repository_id` names no repository in this organization's installations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"That source repository is busy with another deploy. Also returned when a request with this Idempotency-Key is still executing (`idempotency_in_progress`); retry it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Name does not yield a valid slug, or the agent is invalid. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The repository is linked but its sync could not be queued. Retry with the SAME Idempotency-Key: a 5xx is never stored, so the retry re-drives the sync while the key still protects you from linking twice.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncNotQueuedResponse"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/agents/from_template":{"post":{"summary":"Create an agent from a built-in template","operationId":"createAgentFromTemplate","tags":["agents"],"description":"The headless twin of the console's new-agent form: creates the agent and publishes release v1 from a built-in template (`GET /agent_templates` lists them), so the agent serves without a first push. Requires `agents:write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentFromTemplateRequest"}}}},"responses":{"201":{"description":"The agent was created and release v1 is live.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentFromTemplateResponse"}}}},"202":{"description":"The agent was created and release v1 is still building.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentFromTemplateResponse"}}}},"403":{"description":"Caller lacks agents:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unknown template or harness, a slug that is taken, or a first build that failed. The agent exists in the last case. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/agents/{slug}/deploy":{"post":{"summary":"Redeploy a GitHub-connected agent","operationId":"deployAgent","tags":["agents"],"description":"Re-syncs the agent's source repository through the mirror gate, which rebuilds it at deploy-branch HEAD, instead of waiting for a push webhook. Answers when the sync is QUEUED, not when the release is built: poll `GET /api/agents/{slug}/releases`. Requires `releases:write` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"The re-sync is queued.","content":{"application/json":{"schema":{"type":"object","required":["agent","queued","source_repo"],"properties":{"agent":{"$ref":"#/components/schemas/AgentSettingsAgent"},"queued":{"type":"boolean"},"source_repo":{"type":"object","required":["slug","deploy_branch"],"properties":{"slug":{"type":"string"},"deploy_branch":{"type":"string"},"github_repository":{"type":["string","null"]}}},"sync_generation":{"type":["integer","null"]},"sync_attempt":{"type":["integer","null"]}}}}}},"403":{"description":"Caller lacks releases:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug (or another organization's agent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The agent is archived, or has no linked GitHub repository. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The sync could not be queued. Retry with the SAME Idempotency-Key: a 5xx is never stored, so the retry re-drives the sync while the key still protects you from deploying twice.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncNotQueuedResponse"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/code":{"put":{"summary":"Save an agent's source files","operationId":"updateAgentCode","tags":["agents"],"description":"Publishes the edited files as release vN+1, the same save the console code editor performs. `base_version` is optimistic concurrency: a save against a stale version is a 409 rather than a silent clobber. Requires `agents:write` scope and dashboard edits enabled on the agent.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCodeUpdateRequest"}}}},"responses":{"200":{"description":"The save published a release, or changed nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCodeUpdateResponse"}}}},"202":{"description":"The save published a release that is still building.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCodeUpdateResponse"}}}},"403":{"description":"Caller lacks agents:write scope, or dashboard edits are disabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug (or another organization's agent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"base_version is stale; reload before saving. Also returned when a request with this Idempotency-Key is still executing (`idempotency_in_progress`); retry it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"A file is too large, or the merged tree is over the aggregate cap.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A missing or non-positive base_version, a `files` map that is not an object of strings, an unknown path, a binary file, an empty entry file, or invalid dharta.toml. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"}}}},"/api/agents/{slug}":{"get":{"summary":"Show an agent's live URLs","operationId":"showAgent","tags":["agents"],"description":"Backs `dharta open`: agent_url (the hosted chat page) and console_url come from the server so clients never re-derive the host scheme. Requires `agents:read` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent and its URLs.","content":{"application/json":{"schema":{"type":"object","required":["agent","clone_url","agent_url","console_url","live_version"],"properties":{"agent":{"type":"object","required":["id","slug","name","deploy_branch","model","resolved_model"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"deploy_branch":{"type":"string"},"workspace_inspectable":{"type":"boolean"},"workspace_access":{"type":"object","additionalProperties":true},"model":{"$ref":"#/components/schemas/AgentModel"},"resolved_model":{"$ref":"#/components/schemas/ResolvedModel"}}},"clone_url":{"type":"string"},"agent_url":{"type":"string"},"console_url":{"type":"string"},"live_version":{"type":["integer","null"]}}}}}},"404":{"description":"Unknown slug (or another organization's agent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Archive an agent","operationId":"deleteAgent","tags":["agents"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Archived agent.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"Caller lacks agents:delete scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/invocations":{"get":{"summary":"Last invocation for an agent","operationId":"getAgentInvocation","tags":["agents"],"description":"The most recent turn recorded for the agent, or for one session with `session_id`. Backs the post-deploy smoke test's image_verified verdict. Requires `agents:read` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"session_id","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The most recent turn, or an empty verdict when none exists yet.","content":{"application/json":{"schema":{"type":"object","required":["pending"],"properties":{"pending":{"type":"boolean","description":"No turn has been recorded yet."},"session_id":{"type":["string","null"]},"harness_slug":{"type":["string","null"]},"harness_version":{"type":["string","null"]},"image_digest":{"type":["string","null"]},"reported_harness_slug":{"type":["string","null"]},"reported_harness_version":{"type":["string","null"]},"image_verified":{"type":["boolean","null"]}}}}}},"403":{"description":"Caller lacks agents:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Agent is not in the calling organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{slug}/logs":{"get":{"summary":"Poll runtime log summaries for an agent","operationId":"listAgentLogs","tags":["agents"],"description":"Backs `dharta logs`. Returns durable per-turn usage summaries, not transcript content. Requires `agents:read` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"tail","in":"query","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Runtime log summary rows.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","required":["ts","message"],"properties":{"ts":{"type":"string","format":"date-time"},"level":{"type":["string","null"]},"message":{"type":"string"}}}},"next_since":{"type":["string","null"],"format":"date-time"}}}}}},"403":{"description":"Caller lacks agents:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug (or another organization's agent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid since timestamp.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{slug}/releases":{"get":{"summary":"List releases for an agent","operationId":"listAgentReleases","tags":["releases"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent production releases.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}}},"/api/agents/{slug}/releases/{version}/activate":{"post":{"summary":"Activate a release","operationId":"activateAgentRelease","tags":["releases"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Activated release plus previous release if any.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Release cannot be activated. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/releases/{version}/retry":{"post":{"summary":"Retry a failed browser-created release","operationId":"retryAgentRelease","tags":["releases"],"description":"Republishes a FAILED release that was created in the browser, as release vN+1, from its retained source or from the template the agent was created with. Requires `releases:write` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The retry published a release that is already built.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseRetryResponse"}}}},"202":{"description":"The retry published a release that is still building.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseRetryResponse"}}}},"403":{"description":"Caller lacks releases:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown agent or release.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The release is not a failed browser-created production release, no retryable source survives, or the new release failed to build. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/releases/{version}/archive":{"get":{"summary":"Download a release source archive","operationId":"getReleaseArchive","tags":["releases"],"description":"Returns a short-lived signed URL for the exact tree the release serves, so `dharta dev --release vN` can run production code locally. Source leaves the platform, so every pull records a `release_archive.pulled` audit event. Requires the bounded `source_archives:read` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A signed URL for the release tarball.","content":{"application/json":{"schema":{"type":"object","required":["version","commit_sha","url"],"properties":{"version":{"type":"integer"},"commit_sha":{"type":"string"},"url":{"type":"string","format":"uri","description":"Signed, expiring download URL."}}}}}},"403":{"description":"Caller lacks source_archives:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Release or archive is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{slug}/rollback":{"post":{"summary":"Roll back to a previous release","operationId":"rollbackAgentRelease","tags":["releases"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to_version"],"properties":{"to_version":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Activated prior release plus previous release if any.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"Caller lacks releases:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown agent or release.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Release cannot be rolled back to. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/publish":{"post":{"summary":"Publish an agent by upload","operationId":"publishAgent","tags":["releases"],"description":"Backs `dharta deploy --mode folder`. CI posts a gzipped tarball of the agent project; the agent is created on first publish, and the release is materialized and activated before the response returns. Requires `releases:write` scope. Body is multipart/form-data, not JSON.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["tarball","commit_sha"],"properties":{"tarball":{"type":"string","format":"binary","description":"gzipped tar of the project. 200 MB maximum."},"commit_sha":{"type":"string"},"name":{"type":"string","maxLength":100,"description":"Display name, set on first publish."}}}}}},"responses":{"201":{"description":"The release was built and activated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishResponse"}}}},"202":{"description":"The release is still building; poll the agent for its status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishResponse"}}}},"403":{"description":"Caller lacks releases:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid slug or name, archived agent, or a failed build.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Dharta could not persist the source archive; no release was activated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/source_repos":{"post":{"summary":"Provision a hosted source repository","operationId":"createSourceRepo","tags":["releases"],"description":"Backs `dharta deploy --mode git`. Resolves the hosted repo the selected agent pushes into, provisioning one when it does not exist yet, and returns the clone URL the CLI wires as the `dharta` remote. Agents are discovered from the push rather than created here. Idempotent by construction. Requires `source_repos:write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepoRequest"}}}},"responses":{"201":{"description":"A repository was provisioned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepoResponse"}}}},"200":{"description":"The repository already existed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepoResponse"}}}},"403":{"description":"Caller lacks source_repos:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Ambiguous or invalid agent selection, or the selected agent is connected to GitHub and does not accept hosted git pushes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/github_repositories":{"get":{"summary":"List installed GitHub repositories","operationId":"listGithubRepositories","tags":["releases"],"description":"The repositories the Dharta GitHub App is installed on for this organization - the same picker the console's new-agent page renders. Send an `id` from here as `github_repository_id` to `POST /api/agents`. Requires `source_repos:read` scope.","responses":{"200":{"description":"Installed repositories, by full name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GithubRepositoryList"}}}},"403":{"description":"Caller lacks source_repos:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/source_repos/{slug}/github":{"delete":{"summary":"Disconnect GitHub auto-deploy from a hosted source repository","operationId":"disconnectSourceRepoGithub","tags":["releases"],"description":"Stops pushes to the linked GitHub repository from producing releases. Current releases stay live and per-agent GitHub Actions workflows keep deploying independently. Disconnecting a source that is already disconnected returns 200 with `changed: false`. Requires `source_repos:write` scope on a key created by a current owner or admin.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The current binding state.","content":{"application/json":{"schema":{"type":"object","required":["source_repo","github_repository","changed"],"properties":{"source_repo":{"type":"object","required":["slug","deploy_branch"],"properties":{"slug":{"type":"string"},"deploy_branch":{"type":"string"}}},"github_repository":{"type":["string","null"],"description":"The repository that was disconnected, or null when nothing changed."},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks source_repos:write scope, or the key's creator is not a current owner or admin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No source repository with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The source repository is busy with another deploy. Retry. Also returned when a request with this Idempotency-Key is still executing (`idempotency_in_progress`); retry it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/instructions":{"get":{"summary":"Get an agent's CLAUDE.md instructions","operationId":"getAgentInstructions","tags":["instructions"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current instructions.","content":{"application/json":{"schema":{"type":"object","required":["content","version","editable"],"properties":{"content":{"type":["string","null"]},"version":{"type":["integer","null"]},"editable":{"type":"boolean"}}}}}}}},"put":{"summary":"Update an agent's CLAUDE.md instructions","operationId":"updateAgentInstructions","tags":["instructions"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content","base_version"],"properties":{"content":{"type":"string"},"base_version":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated instructions release.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"409":{"description":"Base version is stale. Also returned when a request with this Idempotency-Key is still executing (`idempotency_in_progress`); retry it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Content is too large.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Dashboard edits are disabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/appearance":{"get":{"summary":"Get an agent's embed appearance","operationId":"getAgentAppearance","tags":["appearance"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stored and resolved appearance.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"patch":{"summary":"Update an agent's embed appearance","operationId":"updateAgentAppearance","tags":["appearance"],"description":"Merges at the TOP LEVEL only: keys you leave out keep their value, and a key sent as `null` (or `\"\"`) is CLEARED, which is what clearing the field in the console does; the token then falls back to the preset.\n\n`colors` is the exception. It REPLACES the whole palette rather than merging into it, so send every colour you want to keep. `colors: null` clears the palette, and so does a `colors` object whose values are all blank - `{\"colors\": {\"light\": {\"accent\": null}}}` leaves nothing behind and therefore clears it. This matches the console form, which submits the whole palette every time.\n\nTwo places where this endpoint and the console form differ, both deliberate:\n\n1. This endpoint can CLEAR `preset`, the enum tokens, and the icon glyphs. The console form drops blank values before saving, so it can only ever set them.\n2. The console form does not render icon inputs, and a console save replaces the whole visual set. An icon glyph set through this endpoint is therefore dropped the next time anyone saves the appearance page. Treat icons as API-owned until the console grows controls for them.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Stored and resolved appearance.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid appearance. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/name":{"patch":{"summary":"Rename an agent","operationId":"renameAgent","tags":["agents"],"description":"Changes the DISPLAY name only. The slug is the agent's identity in URLs, deploys and every other endpoint, and never changes here. A deploy whose dharta.toml declares a `name` overwrites this on publish. Requires `agents:write` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRenameRequest"}}}},"responses":{"200":{"description":"The agent, and whether the name changed.","content":{"application/json":{"schema":{"type":"object","required":["agent","changed"],"properties":{"agent":{"$ref":"#/components/schemas/AgentSettingsAgent"},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks agents:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug (or another organization's agent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Display name must be 1-100 characters. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/durable_workspace":{"patch":{"summary":"Enable or disable the durable workspace","operationId":"updateAgentDurableWorkspace","tags":["agents"],"description":"A cost setting: it decides whether the agent's kartas write to the durable store, which is billed per GB and never garbage-collected. Enforced in the runtime environment, so it takes effect on the agent's next release; stored data is untouched either way. Requires `agents:write` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentToggleRequest"}}}},"responses":{"200":{"description":"The agent, and whether the setting changed.","content":{"application/json":{"schema":{"type":"object","required":["agent","changed"],"properties":{"agent":{"$ref":"#/components/schemas/AgentSettingsAgent"},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks agents:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug (or another organization's agent).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`enabled` is missing or is not a boolean. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/serving":{"patch":{"summary":"Enable or disable public serving","operationId":"updateAgentServing","tags":["agents"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Updated agent setting.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid setting. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/dashboard_edits":{"patch":{"summary":"Enable or disable dashboard edits","operationId":"updateAgentDashboardEdits","tags":["agents"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Updated agent setting.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid setting. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/model":{"patch":{"summary":"Update an agent's model override","operationId":"updateAgentModel","tags":["agents"],"description":"Sets the agent's connector policy and model reference. An empty `connector_order` hands the agent back to the organization settings.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentModelUpdateRequest"}}}},"responses":{"200":{"description":"The agent and its stored model policy. Read the agent to see what that resolves to.","content":{"application/json":{"schema":{"type":"object","required":["agent"],"properties":{"agent":{"$ref":"#/components/schemas/AgentSettingsAgent"}}}}}},"403":{"description":"Caller lacks agents:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Agent not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid model settings. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/workspace_inspectable":{"patch":{"summary":"Enable or disable workspace inspection","operationId":"updateAgentWorkspaceInspectable","tags":["agents"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Updated agent setting.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid setting. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/workspace_access":{"patch":{"summary":"Update the workspace access grant matrix","operationId":"updateAgentWorkspaceAccess","tags":["agents"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Updated agent setting.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid setting. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/schedules":{"get":{"summary":"List schedules for an agent","description":"Returns the agent's recurring (cron) and one-shot (run_at) schedules. Each row carries an `origin`: `operator` (created here or in the console) or `agent` (a one-shot wakeup the running agent scheduled for itself).","operationId":"listAgentSchedules","tags":["schedules"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recurring and one-shot schedules.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}},"post":{"summary":"Create a schedule (recurring or one-shot)","description":"Provide exactly one trigger: `cron` (five-field, evaluated in `timezone`) for a recurring schedule, or `run_at` (a future ISO 8601 timestamp) for a one-shot that fires once and then disables itself, keeping its run history.","operationId":"createAgentSchedule","tags":["schedules"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"201":{"description":"Created schedule.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid schedule. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/schedules/{id}":{"delete":{"summary":"Delete a schedule","operationId":"deleteAgentSchedule","tags":["schedules"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Deleted."},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/schedules/{id}/pause":{"post":{"summary":"Pause a schedule","operationId":"pauseAgentSchedule","tags":["schedules"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated schedule.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/schedules/{id}/resume":{"post":{"summary":"Resume a schedule","operationId":"resumeAgentSchedule","tags":["schedules"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated schedule.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/schedules/{id}/run":{"post":{"summary":"Queue a scheduled run immediately","operationId":"runAgentSchedule","tags":["schedules"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated schedule.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/embed_keys":{"get":{"summary":"List publishable embed keys for an agent","operationId":"listEmbedKeys","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Publishable embed keys.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}},"post":{"summary":"Create a publishable embed key","operationId":"createEmbedKey","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"201":{"description":"Created key plus one-time secret.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid embed key. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/agents/{slug}/embed_keys/{id}":{"patch":{"summary":"Update a publishable embed key","operationId":"updateEmbedKey","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Updated embed key.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid embed key. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Revoke a publishable embed key","operationId":"revokeEmbedKey","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Revoked."},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/embed_keys/{id}/rotate":{"post":{"summary":"Rotate a publishable embed key","operationId":"rotateEmbedKey","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated embed key.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/embed_keys/{id}/disable":{"post":{"summary":"Disable a publishable embed key","operationId":"disableEmbedKey","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated embed key.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/embed_keys/{id}/enable":{"post":{"summary":"Enable a publishable embed key","operationId":"enableEmbedKey","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated embed key.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/embed_keys/{id}/identity":{"post":{"summary":"Enable verified identity and reveal its one-time signing secret","operationId":"enableEmbedKeyIdentity","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated embed key plus one-time identity signing secret.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Verified identity cannot be enabled on a revoked key. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Disable verified identity for a publishable embed key","operationId":"disableEmbedKeyIdentity","tags":["embed_keys"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated embed key.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/env":{"get":{"summary":"List env bindings","operationId":"listEnvVars","tags":["env"],"description":"Backs `dharta env list`/`diff`. Secret-marked values never appear; non-secret values do. Requires `env:read` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Env bindings.","content":{"application/json":{"schema":{"type":"object","required":["env"],"properties":{"env":{"type":"array","items":{"$ref":"#/components/schemas/EnvVar"}}}}}}}}}},"/api/agents/{slug}/env/{name}":{"put":{"summary":"Bind an env var","operationId":"setEnvVar","tags":["env"],"description":"Backs `dharta env set`. `secret: true` marks the value excluded-from-pull; unmarking requires delete + re-set. Requires `env:write` scope. Audited.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["value"],"properties":{"value":{"type":"string"},"secret":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVar"}}}},"200":{"description":"Updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVar"}}}},"422":{"description":"Invalid name, or an attempt to unmark a secret. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Remove an env binding","operationId":"unsetEnvVar","tags":["env"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Removed (audited)."},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{agent_slug}/instances/{agent_instance_id}/env":{"get":{"summary":"List a karta's env bindings","operationId":"listInstanceEnvVars","tags":["env"],"description":"Per-karta configuration. Requires `instance_env:read`. Secret values are never returned - unlike agent-level env there is no pull-with-secrets counterpart.","parameters":[{"name":"agent_slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_instance_id","in":"path","required":true,"schema":{"type":"string"},"description":"The karta's raw instance id, or a named karta's vanity slug."}],"responses":{"200":{"description":"Env bindings for this dharta.","content":{"application/json":{"schema":{"type":"object","required":["env"],"properties":{"env":{"type":"array","items":{"$ref":"#/components/schemas/EnvVar"}}}}}}},"404":{"description":"Agent or karta not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{agent_slug}/instances/{agent_instance_id}/env/{name}":{"put":{"summary":"Bind an env var on one karta","operationId":"setInstanceEnvVar","tags":["env"],"description":"Backs `karta kartas env set`. Requires `instance_env:write`. New bindings default to secret. Audited with the acting principal.","parameters":[{"name":"agent_slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_instance_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["value"],"properties":{"value":{"type":"string"},"secret":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVar"}}}},"200":{"description":"Updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVar"}}}},"422":{"description":"Reserved or malformed name, a value a process environment cannot hold, an exceeded budget, or an attempt to unmark a secret. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Remove a karta's env binding","operationId":"unsetInstanceEnvVar","tags":["env"],"parameters":[{"name":"agent_slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"agent_instance_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Removed (audited)."},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/env/pull":{"post":{"summary":"Pull env values","operationId":"pullEnvVars","tags":["env"],"description":"Backs `dharta env pull`. Every pull emits an audit event. Secret-marked values are withheld unless `include_secrets` is set, which requires a bounded `env:secrets:read` key.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"include_secrets":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Values; withheld secrets carry `withheld: true` and no value.","content":{"application/json":{"schema":{"type":"object","required":["env"],"properties":{"env":{"type":"array","items":{"$ref":"#/components/schemas/EnvVar"}}}}}}},"403":{"description":"include_secrets without env:secrets:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/agents/{slug}/session_tokens":{"post":{"summary":"Mint an agent session token","operationId":"createSessionToken","tags":["agents"],"description":"Mints a short-lived, agent-scoped token for a customer backend to hand to a browser. The API key stays on the server; only this token ships to the client. A `sub` asserted here is treated as verified, because the calling backend authenticated its own user first. Requires `agents:write` scope.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionTokenRequest"}}}},"responses":{"201":{"description":"A minted session token.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/MintedToken"},{"type":"object","required":["agent","identity"],"properties":{"agent":{"type":"object","required":["id","slug"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"}}},"identity":{"type":"object","required":["verified"],"properties":{"sub":{"type":"string"},"verified":{"type":"boolean"}}}}}]}}}},"402":{"description":"Organization or end-user spend cap is exhausted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller lacks agents:write scope, the end user is unavailable, or the agent denies access.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Agent is not in the calling organization, or is archived.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Data isolation is required for this agent and no tenant was asserted, or the asserted tenant is unknown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Session token signing is not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{slug}/workspace_tokens":{"post":{"summary":"Mint a workspace git token","operationId":"createWorkspaceToken","tags":["agents"],"description":"Mints a short-lived, read-only git token for one karta durable workspace (RFC 0043). The CLI credential helper calls this and hands the token to the DATA-PLANE git host, so clone bytes never pass through the control plane. Requires the bounded `workspace_tokens:create` scope, and every mint records an `agent.workspace_token_minted` audit event.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceTokenRequest"}}}},"responses":{"201":{"description":"A minted workspace token and the URLs it authorizes.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/MintedToken"},{"type":"object","required":["clone_url","files_url"],"properties":{"clone_url":{"type":"string","format":"uri","description":"Data-plane git remote for the karta workspace."},"files_url":{"type":"string","format":"uri"}}}]}}}},"403":{"description":"Caller lacks workspace_tokens:create scope or workspace:read for the workspace_read channel, or that channel is not granted for this agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Agent is not in the calling organization, or is archived. The karta is not checked: the token names it, and the data plane authorizes it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`instance` is missing, or `scope` is not one of the known channels. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Workspace git access is not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/marketplace/support_grants/{id}/workspace_tokens":{"post":{"summary":"Mint a workspace token from a buyer's support grant","operationId":"createSupportAccessWorkspaceToken","tags":["marketplace"],"description":"Spends a live, buyer-issued support grant for a short-lived, read-only token on that buyer's karta workspace (RFC 0084 D3, RFC 0090 C22). The grant, not the caller's own agent, authorizes the mint, so the karta lives in the buyer's organization. Requires the bounded `workspace_tokens:create` scope, and the `workspace_read` channel additionally requires `workspace:read`. Every mint records a `marketplace.support_grant_used` audit event the buyer can see, which is why this operation is not idempotent.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"The support grant the buyer issued."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportAccessTokenRequest"}}}},"responses":{"201":{"description":"A minted workspace token, the URLs it authorizes, and when the grant itself ends.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/MintedToken"},{"type":"object","required":["grant_expires_at","clone_url","files_url"],"properties":{"grant_expires_at":{"type":"string","format":"date-time","description":"When the buyer's grant expires. Tokens are never minted past it."},"clone_url":{"type":"string","format":"uri","description":"Data-plane git remote for the buyer's karta workspace."},"files_url":{"type":"string","format":"uri"}}}]}}}},"403":{"description":"The grant is not live, does not cover the requested channel, or the caller lacks workspace_tokens:create (or workspace:read for the workspace_read channel).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such grant, or the grant names a different publisher. The same answer for both, so grant ids cannot be probed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Workspace git access is not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/limits/budget":{"get":{"summary":"Get the organization monthly budget cap","operationId":"getBudgetLimit","tags":["limits"],"responses":{"200":{"description":"Budget and current-period usage.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"patch":{"summary":"Update the organization monthly budget cap","operationId":"updateBudgetLimit","tags":["limits"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Budget and current-period usage.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Invalid budget. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/limits/instances/{id}/cap":{"get":{"summary":"Get a durable karta spend cap","operationId":"getInstanceCap","tags":["limits"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Spend cap state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"type":{"type":"string","enum":["instance","end_user"]},"spend_micros":{"type":"integer"},"cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}]}}}}}},"403":{"description":"Caller lacks caps:read or caps:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Set or clear a durable karta spend cap","operationId":"updateInstanceCap","tags":["limits"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cap_cents":{"type":"integer"},"amount_cents":{"type":"integer"},"amount_dollars":{"type":"string"},"clear":{"type":"boolean"},"end_user_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Spend cap state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"type":{"type":"string","enum":["instance","end_user"]},"spend_micros":{"type":"integer"},"cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}]},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks caps:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid cap. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/limits/end_users/{id}/cap":{"get":{"summary":"Get a global end-user spend cap","operationId":"getEndUserCap","tags":["limits"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Spend cap state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"type":{"type":"string","enum":["instance","end_user"]},"spend_micros":{"type":"integer"},"cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}]}}}}}},"403":{"description":"Caller lacks caps:read or caps:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Set or clear a global end-user spend cap","operationId":"updateEndUserCap","tags":["limits"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cap_cents":{"type":"integer"},"amount_cents":{"type":"integer"},"amount_dollars":{"type":"string"},"clear":{"type":"boolean"},"end_user_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Spend cap state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"type":{"type":"string","enum":["instance","end_user"]},"spend_micros":{"type":"integer"},"cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}]},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks caps:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid cap. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/limits/instances/{id}/seat_cap":{"get":{"summary":"Get a per-seat spend cap","operationId":"getSeatCap","tags":["limits"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"end_user_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Spend cap state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"type":{"type":"string","enum":["seat"]},"spend_micros":{"type":"integer"},"cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}]},"raw_instance_id":{"type":"string"},"agent_instance_id":{"type":"string"},"end_user_id":{"type":"string"}}}}}},"403":{"description":"Caller lacks caps:read or caps:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Set or clear a per-seat spend cap","operationId":"updateSeatCap","tags":["limits"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cap_cents":{"type":"integer"},"amount_cents":{"type":"integer"},"amount_dollars":{"type":"string"},"clear":{"type":"boolean"},"end_user_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Spend cap state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"type":{"type":"string","enum":["seat"]},"spend_micros":{"type":"integer"},"cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}]},"raw_instance_id":{"type":"string"},"agent_instance_id":{"type":"string"},"end_user_id":{"type":"string"},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks caps:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid cap. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api_keys":{"get":{"summary":"List API keys","operationId":"listApiKeys","tags":["api_keys"],"responses":{"200":{"description":"API keys for the calling organization.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller lacks keys:read or keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create an API key","operationId":"createApiKey","tags":["api_keys"],"description":"Returns the plaintext secret exactly once. Browser HTML creation remains MFA-backed; bearer JSON creation requires a bounded `keys:write` key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"422":{"description":"Validation failed. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api_keys/{id}":{"patch":{"summary":"Rename an API key","operationId":"renameApiKey","tags":["api_keys"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":200}}}}}},"responses":{"200":{"description":"Renamed.","content":{"application/json":{"schema":{"type":"object","required":["api_key"],"properties":{"api_key":{"$ref":"#/components/schemas/ApiKey"}}}}}},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}},"delete":{"summary":"Revoke an API key","operationId":"revokeApiKey","tags":["api_keys"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Revoked."},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api_keys/{id}/rotate":{"post":{"summary":"Rotate an API key","operationId":"rotateApiKey","tags":["api_keys"],"description":"Mints a replacement carrying this key's scopes, mode, IP allowlist and limits, then retires the original: immediately with `grace_period=now`, otherwise at the end of the window. The replacement's secret is returned once and is never readable again.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRotateRequest"}}}},"responses":{"201":{"description":"Replacement key and its one-time secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRotateResponse"}}}},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unknown rotation window, or the key is not active. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api_keys/{id}/disable":{"post":{"summary":"Disable an API key","operationId":"disableApiKey","tags":["api_keys"],"description":"Suspends the key without retiring it. `changed` is false when the key was already disabled, which is a no-op rather than an error.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Key state.","content":{"application/json":{"schema":{"type":"object","required":["api_key","changed"],"properties":{"api_key":{"$ref":"#/components/schemas/ApiKey"},"changed":{"type":"boolean","description":"False when the key was already in that state."}}}}}},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The key is revoked. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api_keys/{id}/enable":{"post":{"summary":"Re-enable a disabled API key","operationId":"enableApiKey","tags":["api_keys"],"description":"`changed` is false when the key was not disabled. A revoked key can never be re-enabled.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Key state.","content":{"application/json":{"schema":{"type":"object","required":["api_key","changed"],"properties":{"api_key":{"$ref":"#/components/schemas/ApiKey"},"changed":{"type":"boolean","description":"False when the key was already in that state."}}}}}},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The key is revoked. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api_keys/bulk_update":{"post":{"summary":"Apply one state change to several API keys","operationId":"bulkUpdateApiKeys","tags":["api_keys"],"description":"Atomic: every key changes or none does. Keys the action cannot apply to (disabling a revoked key, enabling one that is not disabled) are reported in `skipped` rather than failing the request. Ids outside the calling organization are ignored. The audit log records the per-key event for each key it changed plus one `api_key.bulk_updated` summary event for the batch.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyBulkUpdateRequest"}}}},"responses":{"200":{"description":"What the batch changed and skipped.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyBulkUpdateResponse"}}}},"403":{"description":"Caller lacks keys:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unknown action, or no key in this organization was selected. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/model_connections":{"get":{"summary":"List model connections","operationId":"listModelConnections","tags":["model_connections"],"responses":{"200":{"description":"Model connections for the calling organization.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ModelConnection"}}}}}}},"403":{"description":"Caller lacks model_connections:read or model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Store a provider API key","operationId":"createModelConnection","tags":["model_connections"],"description":"Stores an encrypted-at-rest provider API key. A new connection serves nothing until you enable models on it with `PUT /model_connections/{id}/models`. Browser HTML creation remains MFA-backed; bearer JSON creation requires a bounded `model_connections:write` key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelConnectionCreateRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelConnectionCreateResponse"}}}},"403":{"description":"Caller lacks model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed or unknown provider. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/model_connections/{id}":{"patch":{"summary":"Rotate a model connector credential","operationId":"rotateModelConnection","tags":["model_connections"],"description":"Replaces the stored credential in place. The connector keeps its id and slug, so every agent route that already points at it keeps working.","parameters":[{"name":"id","in":"path","required":true,"description":"Numeric model connector id, or its organization-unique slug. A segment made only of digits is always read as an id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelConnectionRotateRequest"}}}},"responses":{"200":{"description":"Rotated connection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelConnectionCreateResponse"}}}},"403":{"description":"Caller lacks model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No connector matches this id or slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Revoke a model connection","operationId":"revokeModelConnection","tags":["model_connections"],"parameters":[{"name":"id","in":"path","required":true,"description":"Numeric model connector id, or its organization-unique slug. A segment made only of digits is always read as an id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Revoked."},"403":{"description":"Caller lacks model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No connector matches this id or slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/model_connections/{id}/models":{"get":{"summary":"List a connector's models","operationId":"listModelConnectionModels","tags":["model_connections"],"description":"Lists provider-catalog and administrator-defined models for this connection. Only persisted, enabled offers are eligible for resolution; an unconfigured connection reports no enabled models or default.","parameters":[{"name":"id","in":"path","required":true,"description":"Numeric model connector id, or its organization-unique slug. A segment made only of digits is always read as an id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Connector models.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectorOffers"}}}},"403":{"description":"Caller lacks model_connections:read or model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No serving connector matches this id or slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Replace a connector's enabled models","operationId":"configureModelConnectionModels","tags":["model_connections"],"description":"Replaces the whole enabled set and the connector default.","parameters":[{"name":"id","in":"path","required":true,"description":"Numeric model connector id, or its organization-unique slug. A segment made only of digits is always read as an id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectorOffersRequest"}}}},"responses":{"200":{"description":"Connector models.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectorOffers"}}}},"403":{"description":"Caller lacks model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No serving connector matches this id or slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed, for example a default outside the enabled set. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/organization/model_settings":{"get":{"summary":"Get the organization model settings","operationId":"getOrganizationModelSettings","tags":["model_connections"],"responses":{"200":{"description":"Organization model settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationModelSettingsResponse"}}}},"403":{"description":"Caller lacks model_connections:read or model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Update the organization model settings","operationId":"updateOrganizationModelSettings","tags":["model_connections"],"description":"Only the keys you send change. Agents that inherit these settings are re-validated before the write commits, so an incompatible order or model is rejected rather than breaking serving. `provider_endpoint_url` and `provider_endpoint_kind` are the same optional endpoint override the console writes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationModelSettingsUpdateRequest"}}}},"responses":{"200":{"description":"Organization model settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationModelSettingsResponse"}}}},"403":{"description":"Caller lacks model_connections:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/user_model_connections":{"get":{"summary":"List your subscription model connections","operationId":"listUserModelConnections","tags":["model_connections"],"security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Connections for the signed-in user.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserModelConnection"}}}}}}},"401":{"description":"A signed-in Dharta user is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a pending subscription model connection","operationId":"createUserModelConnection","tags":["model_connections"],"security":[{"cookieAuth":[]}],"description":"Creates non-secret metadata and a server-generated provider-client cell reference. The request never carries provider credentials or cell metadata.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["provider","agent_id"],"properties":{"provider":{"type":"string","enum":["openai","xai"]},"agent_id":{"type":"integer","minimum":1},"name":{"type":"string","maxLength":100}}}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"type":"object","required":["model_connection"],"properties":{"model_connection":{"$ref":"#/components/schemas/UserModelConnection"}}}}}},"401":{"description":"A signed-in Dharta user is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Provider or profile metadata is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/user_model_connections/{id}/status":{"get":{"summary":"Get subscription connection status","operationId":"getUserModelConnectionStatus","tags":["model_connections"],"security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Current non-secret status.","content":{"application/json":{"schema":{"type":"object","required":["model_connection"],"properties":{"model_connection":{"$ref":"#/components/schemas/UserModelConnection"}}}}}},"401":{"description":"A signed-in Dharta user is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No connection belongs to this user and Agent release.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/user_model_connections/{id}/logout":{"post":{"summary":"Request provider-client logout","operationId":"logoutUserModelConnection","tags":["model_connections"],"security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Logout requested.","content":{"application/json":{"schema":{"type":"object","required":["model_connection","changed"],"properties":{"model_connection":{"$ref":"#/components/schemas/UserModelConnection"},"changed":{"type":"boolean"}}}}}},"401":{"description":"A signed-in Dharta user is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No connection belongs to this user and Agent release.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/user_model_connections/{id}":{"delete":{"summary":"Revoke a subscription model connection","operationId":"revokeUserModelConnection","tags":["model_connections"],"security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"type":"object","required":["model_connection","changed"],"properties":{"model_connection":{"$ref":"#/components/schemas/UserModelConnection"},"changed":{"type":"boolean"}}}}}},"401":{"description":"A signed-in Dharta user is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No connection belongs to this user and Agent release.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhook_endpoints":{"get":{"summary":"List webhook endpoints","operationId":"listWebhookEndpoints","tags":["webhook_endpoints"],"responses":{"200":{"description":"Webhook endpoints.","content":{"application/json":{"schema":{"type":"object","required":["data","event_types"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"event_types":{"type":"array","items":{"type":"string","enum":["api_key.created","api_key.revoked","subscription.created","subscription.updated","subscription.canceled","invoice.paid","invoice.payment_failed","organization.suspended","organization.resumed","usage.budget_threshold_reached","usage.budget_exhausted","session.started","turn.completed","turn.failed"]},"description":"Every event type an endpoint can subscribe to."}}}}}}}},"post":{"summary":"Create a webhook endpoint","operationId":"createWebhookEndpoint","tags":["webhook_endpoints"],"description":"Requires `webhooks:write`, a tenant-administration scope: the key must carry an expiry within 90 days. A destination is an egress trust root. Any URL is accepted, and omitting `event_types` subscribes the endpoint to every event type, which carries billing, API-key, session and turn data.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreateRequest"}}}},"responses":{"201":{"description":"Created. Signing secret shown once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreateResponse"}}}},"422":{"description":"Validation failed. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/webhook_endpoints/{id}":{"patch":{"summary":"Update a webhook endpoint","operationId":"updateWebhookEndpoint","tags":["webhook_endpoints"],"description":"Applies whichever of `name`, `url` and `event_types` is present; an absent key leaves that field alone. Re-enabling a disabled endpoint is a separate operation: POST /api/webhook_endpoints/{id}/enable.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdateRequest"}}}},"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointEnvelope"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Delete a webhook endpoint","operationId":"deleteWebhookEndpoint","tags":["webhook_endpoints"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Deleted."},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/webhook_endpoints/{id}/enable":{"post":{"summary":"Re-enable a webhook endpoint","operationId":"enableWebhookEndpoint","tags":["webhook_endpoints"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointEnvelope"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/webhook_endpoints/{id}/test":{"post":{"summary":"Send a test event to a webhook endpoint","operationId":"testWebhookEndpoint","tags":["webhook_endpoints"],"description":"Queues one `webhook.test` delivery through the production path: the same delivery row, the same signature, the same retries. The response reports the queued delivery, not its outcome; the outcome lands on the delivery row and in Recent deliveries.\n\nRate limited per endpoint. An accepted request spends one unit of the budget whether or not the destination ever answers, because the budget bounds what this endpoint sends, not what comes back. A `429` spends nothing.\n\nRetry a `429` with the **same** `Idempotency-Key`. A 429 is never stored, so the retry sends the test event while the key still stops one test event being sent twice.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Test delivery queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryResponse"}}}},"403":{"description":"Caller lacks webhooks:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The endpoint is disabled. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Test events for this endpoint are rate limited. `Retry-After` names the seconds to wait. Retry with the **same** `Idempotency-Key`: a 429 is never stored, so the key is still free to stop one test event being sent twice.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/usage":{"get":{"summary":"Usage summary for the current billing period","operationId":"getUsageSummary","tags":["usage"],"responses":{"200":{"description":"Current-period usage rollup and budget state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"}}}}}}},"/api/analytics/agents":{"get":{"summary":"Agent analytics","operationId":"getAgentAnalytics","tags":["analytics"],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Analytics trend and rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEntityResponse"}}}},"403":{"description":"Caller lacks analytics:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/users":{"get":{"summary":"End-user analytics","operationId":"getUserAnalytics","tags":["analytics"],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Analytics trend and rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEntityResponse"}}}},"403":{"description":"Caller lacks analytics:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/instances":{"get":{"summary":"Durable karta analytics","operationId":"getInstanceAnalytics","tags":["analytics"],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Analytics trend and rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEntityResponse"}}}},"403":{"description":"Caller lacks analytics:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/sessions":{"get":{"summary":"Session analytics","operationId":"getSessionAnalytics","tags":["analytics"],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Analytics trend and rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEntityResponse"}}}},"403":{"description":"Caller lacks analytics:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/models":{"get":{"summary":"Model analytics","operationId":"getModelAnalytics","tags":["analytics"],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Analytics trend and rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEntityResponse"}}}},"403":{"description":"Caller lacks analytics:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/analytics/cost":{"get":{"summary":"Cost analytics","operationId":"getCostAnalytics","tags":["analytics"],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","enum":["mtd","7d","30d","last_month","90d","custom"]}},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","enum":["agent","karta","session","user","model"]}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"Cost totals, daily series, and grouped rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsCostResponse"}}}},"403":{"description":"Caller lacks analytics:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/members":{"get":{"summary":"List organization members and invitations","operationId":"listMembers","tags":["members"],"responses":{"200":{"description":"Members and pending invitations.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"Caller lacks members:read or member-management authority.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/members/invitations":{"post":{"summary":"Invite an organization member","operationId":"inviteMember","tags":["members"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"201":{"description":"Created invitation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationResponse"}}}},"403":{"description":"Caller lacks members:invite or owner-role authority.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid invitation. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/members/invitations/{id}":{"delete":{"summary":"Revoke a pending invitation","operationId":"revokeMemberInvitation","tags":["members"],"description":"Pending invitations only; an accepted invitation is history and returns 404. Requires `members:invite` scope on a key created by a current owner or admin.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Revoked."},"403":{"description":"Caller lacks members:invite or member-management authority.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No pending invitation with that id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/members/invitations/{id}/resend":{"post":{"summary":"Re-send a pending invitation","operationId":"resendMemberInvitation","tags":["members"],"description":"Re-arms the expiry window and mails the invitee again. The token is unchanged, so the link in the original email keeps working. Send an `Idempotency-Key`: a retry without one mails the invitee twice. Rate limited per invitation across the API and the console alike. Requires `members:invite` scope on a key created by a current owner or admin.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The re-armed invitation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationResponse"}}}},"403":{"description":"Caller lacks members:invite or member-management authority.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No pending invitation with that id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"That invitation has been re-sent too many times. The limit is per invitation and is shared with the console.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","required":true,"schema":{"type":"integer","minimum":0}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/members/{id}":{"patch":{"summary":"Change a member role","operationId":"updateMemberRole","tags":["members"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Updated member.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"403":{"description":"Caller lacks member-management authority.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid role change. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Remove a member","operationId":"removeMember","tags":["members"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Removed."},"403":{"description":"Caller lacks member-management authority.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid removal. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/organization":{"patch":{"summary":"Rename the organization","operationId":"renameOrganization","tags":["organization"],"description":"Changes the display name only. The slug is the API and audit identity and cannot be changed. Renaming to the name the organization already has returns 200 with `changed: false` and records nothing. Requires `organization:write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":200}}}}}},"responses":{"200":{"description":"The organization after the rename.","content":{"application/json":{"schema":{"type":"object","required":["organization","changed"],"properties":{"organization":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks organization:write scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Missing `name`, a `name` that is not a JSON string, or one longer than 200 characters. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/organization/support_access":{"patch":{"summary":"Allow or block Dharta support access to session content","operationId":"updateSupportAccess","tags":["organization"],"description":"Owner-only, and the API key's creator must be a current owner of the organization. Requires `organization:support_access:write`, which forces a key expiry within 90 days. Free-plan organizations cannot change the setting.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["allowed"],"properties":{"allowed":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The setting after the change.","content":{"application/json":{"schema":{"type":"object","required":["support_access","changed"],"properties":{"support_access":{"type":"object","required":["allowed"],"properties":{"allowed":{"type":"boolean"}}},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks organization:support_access:write scope, or the key's creator is not a current owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Missing or non-boolean `allowed`, or the organization's plan locks the setting on (`support_access_locked`). Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/organization/support_access/transcripts":{"patch":{"summary":"Allow or block API keys from reading end-user transcripts","operationId":"updateTranscriptAccess","tags":["organization"],"description":"Governs whether API keys may read end-user transcript content through `GET /api/agents/{slug}/directories/sessions` and `dharta sessions show`. Off by default. Owner-only, and the API key's creator must be a current owner of the organization. Requires `organization:support_access:write`, which forces a key expiry within 90 days.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The setting after the change.","content":{"application/json":{"schema":{"type":"object","required":["transcript_access","changed"],"properties":{"transcript_access":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}},"changed":{"type":"boolean"}}}}}},"403":{"description":"Caller lacks organization:support_access:write scope, or the key's creator is not a current owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Missing or non-boolean `enabled`. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/agents/{slug}/directories/instances":{"get":{"summary":"List durable kartas for an agent","operationId":"listDirectoryInstances","tags":["directories"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent-scoped karta rows.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DirectoryInstance"}}}}}}},"403":{"description":"Caller lacks directories:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{slug}/directories/end_users":{"get":{"summary":"List end-users for an agent","operationId":"listDirectoryEndUsers","tags":["directories"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent-scoped end-user rows.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DirectoryEndUser"}}}}}}},"403":{"description":"Caller lacks directories:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agents/{slug}/directories/sessions":{"get":{"summary":"List sessions for an agent","operationId":"listDirectorySessions","tags":["directories"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agent-scoped session rows.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DirectorySession"}}}}}}},"403":{"description":"Caller lacks directories:read scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/billing":{"get":{"summary":"Billing status (plan + subscription)","operationId":"getBillingStatus","tags":["billing"],"responses":{"200":{"description":"Current plan and Stripe subscription state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingStatus"}}}}}}},"/api/fleet/operations":{"post":{"summary":"Preview a bulk fleet change","description":"Freezes the selected targets into an immutable manifest and records a draft operation. Nothing is applied until the draft is confirmed with the returned `confirmation_phrase`.","operationId":"createFleetOperation","tags":["fleet"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetOperationRequest"}}}},"responses":{"201":{"description":"The frozen draft operation.","content":{"application/json":{"schema":{"type":"object","required":["operation"],"properties":{"operation":{"$ref":"#/components/schemas/FleetOperation"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key may not run this action on this entity type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Fleet operations are not enabled for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unknown action, empty selection, or invalid parameters. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/fleet/operations/{id}/confirm":{"post":{"summary":"Confirm and queue a bulk fleet change","operationId":"confirmFleetOperation","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated operation.","content":{"application/json":{"schema":{"type":"object","required":["operation"],"properties":{"operation":{"$ref":"#/components/schemas/FleetOperation"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key may not run this action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such operation, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The operation is no longer a draft, or the phrase does not match. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"Applies the frozen manifest. `confirmation_phrase` must match the phrase the preview returned. It is derived from the frozen manifest, which does not change after the preview, so it proves the caller saw that preview and nothing about drift since.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetOperationConfirmRequest"}}}}}},"/api/fleet/operations/{id}/cancel":{"post":{"summary":"Cancel a bulk fleet change","operationId":"cancelFleetOperation","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated operation.","content":{"application/json":{"schema":{"type":"object","required":["operation"],"properties":{"operation":{"$ref":"#/components/schemas/FleetOperation"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key may not run this action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such operation, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The operation has already finished. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"Stops work that has not started. Changes already applied are not reversed; roll them back with a new operation."}},"/api/fleet/operations/{id}/retry":{"post":{"summary":"Retry the failed targets of a bulk fleet change","operationId":"retryFleetOperation","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated operation.","content":{"application/json":{"schema":{"type":"object","required":["operation"],"properties":{"operation":{"$ref":"#/components/schemas/FleetOperation"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key may not run this action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such operation, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The operation is still running, or has no failed targets. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"Requeues only the targets that failed, leaving successful ones alone."}},"/api/fleet/rollouts/{id}/advance":{"post":{"summary":"Start the next rollout ring","operationId":"advanceFleetRollout","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated rollout.","content":{"application/json":{"schema":{"type":"object","required":["rollout"],"properties":{"rollout":{"$ref":"#/components/schemas/FleetRollout"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such rollout, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The current ring has not passed its health checks, or the rollout would exceed an agent's pinned-release budget. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"Starts the first ring of a draft rollout, or promotes the current ring once its health checks have passed."}},"/api/fleet/rollouts/{id}/pause":{"post":{"summary":"Pause a rollout","operationId":"pauseFleetRollout","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated rollout.","content":{"application/json":{"schema":{"type":"object","required":["rollout"],"properties":{"rollout":{"$ref":"#/components/schemas/FleetRollout"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such rollout, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The rollout is not running or observing. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"Holds the rollout where it is. Changes already in flight may finish."}},"/api/fleet/rollouts/{id}/resume":{"post":{"summary":"Resume a paused rollout","operationId":"resumeFleetRollout","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated rollout.","content":{"application/json":{"schema":{"type":"object","required":["rollout"],"properties":{"rollout":{"$ref":"#/components/schemas/FleetRollout"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such rollout, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The rollout is not paused, or its current ring has no operation. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/fleet/rollouts/{id}/evaluate":{"post":{"summary":"Run the rollout health gates now","operationId":"evaluateFleetRollout","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated rollout.","content":{"application/json":{"schema":{"type":"object","required":["rollout"],"properties":{"rollout":{"$ref":"#/components/schemas/FleetRollout"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such rollout, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The request was recorded in the audit log but the queue refused the job, so no evaluation will run. Retry with the SAME `Idempotency-Key`: a 5xx is never stored, so the retry queues the job while the key still protects you from evaluating twice.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}},"description":"Forces an evaluation instead of waiting for the next observation window. The gates may pause or roll the rollout back on their own."}},"/api/fleet/rollouts/{id}/rollback":{"post":{"summary":"Roll a rollout back to its previous release","description":"Queues one operation covering the whole selection, not just the rings already advanced, and finishes the rollout. The response carries the queued operation as well, because that is the part still in progress.","operationId":"rollbackFleetRollout","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The finished rollout and the operation it queued.","content":{"application/json":{"schema":{"type":"object","required":["rollout","operation"],"properties":{"rollout":{"$ref":"#/components/schemas/FleetRollout"},"operation":{"$ref":"#/components/schemas/FleetOperation"}}}}}},"403":{"description":"Caller lacks fleet:operations:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such rollout, or fleet operations are not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The rollout has no eligible rollback release, has not started, or is already rolled back. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}}},"/api/fleet/findings/{id}/acknowledge":{"post":{"summary":"Acknowledge an issue","operationId":"acknowledgeFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/fleet/findings/{id}/snooze":{"post":{"summary":"Snooze an issue","operationId":"snoozeFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`duration` is not one of 1h, 1d or 1w. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetFindingSnoozeRequest"}}}}}},"/api/fleet/findings/{id}/resolve":{"post":{"summary":"Resolve an issue","operationId":"resolveFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/fleet/findings/{id}/reopen":{"post":{"summary":"Reopen a resolved issue","operationId":"reopenFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}},"description":"Returns the issue to open and clears its classification."}},"/api/fleet/findings/{id}/classify":{"post":{"summary":"Classify an issue","operationId":"classifyFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`classification` is missing or is not one of expected, confirmed or muted. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"`expected` and `muted` also resolve the issue; `muted` suppresses future recurrences of the same series.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetFindingClassifyRequest"}}}}}},"/api/fleet/findings/{id}/assign":{"post":{"summary":"Assign an issue to a member","operationId":"assignFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue, or no such membership in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}},"description":"Omit `membership_id` to unassign.","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetFindingAssignRequest"}}}}}},"/api/fleet/findings/{id}/promote":{"post":{"summary":"Promote an issue to a confirmed incident","operationId":"promoteFleetFinding","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/fleet/findings/{id}":{"patch":{"summary":"Attach a runbook to an issue","operationId":"updateFleetFindingRunbook","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"The updated issue.","content":{"application/json":{"schema":{"type":"object","required":["finding"],"properties":{"finding":{"$ref":"#/components/schemas/FleetAnomalyFinding"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key is not a developer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such issue in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`runbook_url` is not an http(s) URL, or is longer than 2000 characters. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"description":"Send an empty `runbook_url` to remove the link.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetFindingRunbookRequest"}}}}}},"/api/fleet/saved_views":{"post":{"summary":"Create a saved fleet view","operationId":"createFleetSavedView","tags":["fleet"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetSavedViewRequest"}}}},"responses":{"201":{"description":"The saved view.","content":{"application/json":{"schema":{"type":"object","required":["saved_view"],"properties":{"saved_view":{"$ref":"#/components/schemas/FleetSavedView"}}}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key may not create a shared or organization-default view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Fleet is not enabled for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid name, visibility, entity type or definition. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/fleet/saved_views/{id}":{"patch":{"summary":"Update a saved fleet view","description":"Both the stored view and the proposed shape are authorized, so a view cannot be retagged onto an entity type the caller may not read.","operationId":"updateFleetSavedView","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetSavedViewRequest"}}}},"responses":{"200":{"description":"The updated view.","content":{"application/json":{"schema":{"type":"object","required":["saved_view"],"properties":{"saved_view":{"$ref":"#/components/schemas/FleetSavedView"}}}}}},"403":{"description":"Caller lacks fleet:write, or may not change this view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such saved view in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid name, visibility, entity type or definition. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}}},"delete":{"summary":"Delete a saved fleet view","operationId":"deleteFleetSavedView","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Deleted."},"403":{"description":"Caller lacks fleet:write, or may not change this view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such saved view in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/fleet/saved_views/{id}/favorite":{"post":{"summary":"Pin a saved fleet view","description":"Idempotent: pinning a view that is already pinned changes nothing.","operationId":"favoriteFleetSavedView","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Applied."},"403":{"description":"Caller lacks fleet:write, or may not see this view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such saved view in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}},"delete":{"summary":"Unpin a saved fleet view","description":"Idempotent: unpinning a view that was not pinned changes nothing.","operationId":"unfavoriteFleetSavedView","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Applied."},"403":{"description":"Caller lacks fleet:write, or may not see this view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such saved view in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/fleet/analytics/saved_views":{"post":{"summary":"Save an Analytics chart","description":"Takes the same parameters an Analytics explorer URL carries, resolves them into a query, and stores that query as a private view pinned to the caller. Saving implies pinning.","operationId":"saveFleetAnalyticsView","tags":["fleet"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetAnalyticsSaveRequest"}}}},"responses":{"201":{"description":"The saved chart.","content":{"application/json":{"schema":{"type":"object","required":["saved_view"],"properties":{"saved_view":{"$ref":"#/components/schemas/FleetSavedView"}}}}}},"403":{"description":"A cost metric needs the billing permission; an end-user or session scope, filter or breakdown needs the session permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Fleet is not enabled, or the comparison chart does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unknown metric, invalid window, or a missing name. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}},"/api/fleet/analytics/saved_views/{id}/pin":{"delete":{"summary":"Unpin a saved Analytics chart","description":"Idempotent. The chart itself is not deleted.","operationId":"unpinFleetAnalyticsView","tags":["fleet"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Applied."},"403":{"description":"Caller lacks fleet:write, or may not see this view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such saved view in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/IdempotencyKeyReused"}}}},"/api/fleet/exports":{"post":{"summary":"Export selected fleet rows as CSV","description":"Returns a CSV of the named rows, capped at 10,000 selections. Cells that would read as a spreadsheet formula are prefixed with an apostrophe. Every export is recorded in the audit log.","operationId":"createFleetExport","tags":["fleet"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetExportRequest"}}}},"responses":{"200":{"description":"The exported rows.","content":{"text/csv":{"schema":{"type":"string"}}}},"403":{"description":"Caller lacks fleet:write, or the membership behind the key may not read kartas, users or sessions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Fleet is not enabled for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unknown entity type, empty selection, or more than 10,000 rows. Also returned when this Idempotency-Key was used for a DIFFERENT request (`idempotency_key_reused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"400":{"$ref":"#/components/responses/IdempotencyKeyTooLong"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-generated key. Send one to make a retry safe: the first response is stored and replayed, so a retry after an ambiguous network failure cannot perform the mutation twice. 5xx and 429 responses are never stored, so retry those with the same key. Maximum 255 characters.","schema":{"type":"string","maxLength":255}}]}}}}