export type ClientOptions = { baseURL: 'https://api.example.com' | 'http://localhost:8080' | (string & {}); }; export type HealthResponse = { status: string; /** * Short release commit SHA (empty outside deployed environments) */ sha?: string; }; export type SuccessResponse = { status: string; message: string; data?: { [key: string]: unknown; }; }; /** * RFC 9457 Problem Details for HTTP APIs */ export type ErrorResponse = { /** * URI reference that identifies the problem type */ type: string; /** * Short, human-readable summary of the problem type */ title: string; /** * HTTP status code */ status: number; /** * Human-readable explanation specific to this occurrence */ detail: string; /** * Application-specific error code */ code: string; /** * Unique request identifier for tracking and debugging */ request_id: string; /** * Timestamp when the error occurred (RFC3339) */ timestamp: string; /** * URI reference that identifies the specific occurrence */ instance?: string; /** * Field-level validation errors (present for validation failures) */ validation_errors?: Array; }; export type PaginatedResponse = { data: Array; /** * Current page number */ page: number; /** * Number of items per page */ limit: number; /** * Total number of records */ total: number; /** * Total number of pages */ total_pages: number; }; /** * Per-source access counts for a single calendar day (UTC), zero-filled. */ export type ResourceAccessDailyCount = { date: string; web: number; cli: number; mcp: number; api: number; total: number; }; export type ResourceAccessMetricsData = { /** * Sum of every access count across the whole window. */ total_accesses: number; range: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; counts: Array; }; export type ResourceAccessMetricsResponse = { status: string; message: string; data: ResourceAccessMetricsData; }; export type User = { id: string; /** * Legacy Google OAuth subject identifier (may be null for non-Google accounts) */ google_id?: string | null; /** * Identity provider name (e.g. "google", "oidc") */ idp_provider?: string | null; /** * Subject identifier from the identity provider */ idp_subject?: string | null; email: string; name: string; avatar_url?: string | null; default_team_id?: string | null; onboarding_completed: boolean; onboarding_completed_at?: string | null; created_at: string; updated_at: string; version: number; }; /** * The authenticated user as returned by GET /api/v1/auth/me — the full User * object plus session-relative flags. `is_instance_admin` lets the SPA gate the * Admin Portal menu and /admin routes; it is UI convenience only, as every * /api/v1/admin* call is authorized server-side regardless. * */ export type CurrentUser = User & { /** * Whether the authenticated user's email is in the configured * auth.instance_admins list (matched case-insensitively). False when the * list is empty (feature dormant). * */ is_instance_admin: boolean; }; /** * Response body returned by GET /api/v1/auth/login containing the authorization URL */ export type LoginResponse = { /** * Identity-provider authorization URL to redirect the user to for authentication */ url: string; }; /** * Response body returned by POST /api/v1/auth/logout */ export type LogoutResponse = { /** * Confirmation message */ message: string; }; /** * One enabled login provider, with display metadata for the login UI */ export type AuthProvider = { /** * Canonical provider name, also the value to pass as the `provider` * query parameter to GET /api/v1/auth/login (e.g. `google`, `github`, * `oidc`). * */ name: string; /** * Human-readable label for the provider button in the login UI */ display_name: string; }; /** * Response body returned by GET /api/v1/auth/providers listing the login * providers enabled in this deployment's configuration. * */ export type ProvidersResponse = { /** * Enabled login providers, stable-sorted by canonical name */ providers: Array; }; /** * Request body for POST /api/v1/auth/dev/login (development environment only) */ export type DevLoginRequest = { /** * Email address to authenticate as */ email: string; /** * Display name for the dev user (defaults to "Dev User" if omitted) */ name?: string; }; export type ApiKey = { id: string; user_id: string; name: string; key_prefix: string; /** * Array of integration codes this API key can access */ integrations: Array<'cli' | 'mcp_server'>; /** * Whether this is a legacy API key (pre-multi-integration) */ is_legacy: boolean; /** * Notes about the migration from legacy system */ migration_notes?: string | null; /** * DEPRECATED: Legacy field for backward compatibility. Use 'integrations' instead. * * @deprecated */ usage_type?: 'cli' | 'mcp' | 'everything'; last_used_at?: string | null; /** * When the key expires. Null means the key never expires. */ expires_at?: string | null; created_at: string; updated_at: string; }; export type CreateApiKeyRequest = { /** * A descriptive name for the API key */ name: string; /** * Array of integration codes to grant access to */ integration_codes: Array<'cli' | 'mcp_server'>; }; export type CreateApiKeyResponse = { api_key: ApiKey; full_key: string; key_prefix: string; }; export type ApiKeyListResponse = { api_keys: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type Prompt = { id: string; name: string; slug: string; description: string; body: string; user_id: string; /** * Team identifier that owns this prompt */ team_id: string; /** * Project identifier that this prompt belongs to */ project_id: string; status: 'draft' | 'published'; /** * Whether this prompt is discoverable via MCP (Model Context Protocol) tools */ mcp_expose: boolean; /** * Whether this prompt has an active, non-expired share */ is_shared: boolean; /** * Labels for categorizing and filtering prompts. null on the wire when the prompt has none (nil slice serialization). */ labels?: Array | null; created_at: string; updated_at: string; /** * Version number for optimistic concurrency control */ version: number; /** * Depth-1 typed neighborhood of this resource — the relations touching it in both directions, newest first, capped at 20. Typed summaries only, never bodies. Populated on the detail GET; empty in list responses. */ related?: Array; /** * Computed embedding-similarity neighborhood of this resource (up to 5), derived live at read time from vector similarity — NOT stored edges and distinct from `related`. Populated on the detail GET; empty otherwise. */ similar?: Array; freshness?: ResourceFreshnessState; }; export type CreatePromptRequest = { name: string; slug: string; description?: string; body: string; /** * Project identifier that this prompt belongs to */ project_id: string; status?: 'draft' | 'published'; /** * Whether this prompt should be discoverable via MCP tools. Defaults to true if not specified. */ mcp_expose?: boolean; /** * Optional labels for categorizing and filtering prompts */ labels?: Array; }; export type UpdatePromptRequest = { name?: string; slug?: string; description?: string; body?: string; /** * Project identifier to move this prompt to a different project */ project_id?: string; status?: 'draft' | 'published'; /** * Whether this prompt should be discoverable via MCP tools */ mcp_expose?: boolean; /** * Labels for categorizing and filtering prompts */ labels?: Array; }; export type PromptListEnvelope = SuccessResponse & { data: PromptListResponse; }; export type PromptListResponse = { prompts: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type PromptVersionListResponse = { /** * Content-version snapshots for the prompt, newest first */ versions: Array; }; export type RenderPromptRequest = { placeholders: { [key: string]: string; }; }; export type RenderPromptResponse = { rendered_body: string; placeholders_missing?: Array; references_used?: Array; /** * Warnings about issues during rendering (e.g., missing references) */ warnings?: Array; }; export type PromptPlaceholdersResponse = { placeholders: Array; }; export type PromptDependencyInfo = { /** * Prompt identifier */ id: string; /** * Prompt slug */ slug: string; /** * Prompt name */ name: string; }; export type PromptDependenciesResponse = { /** * Prompts that reference this prompt */ used_by: Array; /** * Prompts that this prompt references */ uses: Array; }; export type PromptGalleryTemplate = { id: string; title: string; description?: string; content: string; category: string; tags?: Array; metadata?: { [key: string]: unknown; }; created_at: string; updated_at: string; }; export type PromptGalleryCategoryList = Array; export type PromptLabelsEnvelope = SuccessResponse & { data: { labels: Array; }; }; export type PromptGalleryCategory = { category: string; count: number; }; export type PromptGalleryListResponse = { prompts: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type PromptGalleryUsageRequest = { prompt_id: string; }; export type CreateShareRequest = { /** * Type of share: 'public' allows anyone with the link, 'restricted' requires specific email addresses */ share_type: 'public' | 'restricted'; /** * List of email addresses allowed to access the shared prompt (required for 'restricted' shares) */ emails?: Array; }; export type ShareResponse = { /** * Unique token for accessing the shared prompt */ share_token: string; /** * Relative URL path to access the shared prompt */ share_url: string; share_type: 'public' | 'restricted'; /** * List of emails with access (only present for 'restricted' shares) */ emails?: Array; created_at: string; }; export type SharedPromptResponse = { prompt: Prompt; share_type: 'public' | 'restricted'; /** * Prompt body with @references resolved but {{placeholders}} preserved for client substitution */ rendered_body: string; }; export type Agent = { id: string; user_id: string; /** * Team that owns the agent. Immutable after creation. */ team_id: string; name: string; description: string; status: 'active' | 'paused' | 'error'; card_url?: string | null; /** * A2A agent card fetched from card_url */ agent_card?: AgentCard | null; /** * Serialized as null when the agent has no config (Go nil map) */ config: { [key: string]: unknown; } | null; /** * Names of credentials that are set (values are never returned) */ has_credentials?: Array; last_run?: string | null; /** * When the agent card was last re-fetched from card_url */ last_synced_at?: string | null; total_runs: number; success_rate: number; created_at: string; updated_at: string; /** * Optimistic-locking version counter */ version: number; }; export type CreateAgentRequest = { name?: string; description?: string; status?: 'active' | 'paused'; card_url: string; credentials?: { [key: string]: CredentialRequest; }; }; export type UpdateAgentRequest = { name?: string; description?: string; status?: 'active' | 'paused' | 'error'; card_url?: string; credentials?: { [key: string]: CredentialRequest; }; }; export type AgentListResponse = { agents: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type AgentStatsResponse = { total_agents: number; active_agents: number; paused_agents: number; error_agents: number; total_runs: number; avg_success_rate: number; runs_today: number; runs_this_week: number; /** * Serialized as null when there is no recent activity (Go nil slice) */ recent_activities: Array<{ id?: string; agent_id?: string; agent_name?: string; action?: string; status?: 'success' | 'warning' | 'error'; description?: string; created_at?: string; }> | null; }; export type AgentExecution = { id: string; agent_id: string; user_id: string; status: 'running' | 'success' | 'error' | 'pending' | 'submitted' | 'working' | 'completed' | 'failed' | 'cancelled'; input?: { [key: string]: unknown; }; error?: string | null; started_at: string; ended_at?: string | null; /** * Duration in milliseconds */ duration?: number | null; /** * A2A task identifier (streaming executions) */ task_id?: string | null; /** * A2A context identifier (streaming executions) */ context_id?: string | null; /** * Raw A2A task state as reported by the agent (A2A v1.0 values, e.g. TASK_STATE_WORKING / TASK_STATE_COMPLETED / TASK_STATE_CANCELED). Left as an open string because it mirrors the official SDK's states. */ current_state?: string | null; /** * A2A artifacts produced by the execution */ artifacts?: Array<{ [key: string]: unknown; }> | null; /** * Groups related executions into a conversation */ conversation_id?: string | null; /** * Optimistic-locking version counter */ version: number; }; export type CreateAgentExecutionRequest = { /** * Ignored if provided — the agent ID from the URL path is always used. */ agent_id?: string; input?: { [key: string]: unknown; }; }; export type UpdateAgentExecutionRequest = { status: 'running' | 'success' | 'error'; output?: { [key: string]: unknown; }; error?: string; }; export type Activity = { id: string; user_id: string; activity_type: string; entity_type: string; entity_id?: string | null; session_id?: string | null; description: string; metadata: { [key: string]: unknown; }; source_ip?: string | null; user_agent?: string | null; created_at: string; /** * Human-readable name of the referenced entity (omitted when the entity type has no resolvable name or the entity was deleted) */ entity_name?: string | null; /** * Display name of the user who performed the activity (omitted when the user record cannot be found) */ actor_name?: string | null; }; export type CreateActivityRequest = { activity_type: string; entity_type: string; entity_id?: string; session_id?: string; description: string; /** * Arbitrary metadata; the server adds manual_creation and created_via keys */ metadata?: { [key: string]: unknown; }; /** * Ignored — overwritten with the client IP derived from the request */ source_ip?: string; /** * Ignored — overwritten with the User-Agent header from the request */ user_agent?: string; }; export type ActivityListResponse = { activities: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type ActivityStatsResponse = { total_activities: number; activities_today: number; activities_this_week: number; top_activity_types: Array<{ activity_type?: string; count?: number; }>; top_entity_types: Array<{ entity_type?: string; count?: number; }>; recent_activities: Array; activities_by_date_week: Array<{ date?: string; count?: number; }>; }; export type ActivityTypesResponse = { activity_types: Array; entity_types: Array; }; export type EntityTypesResponse = { entity_types: Array; }; export type EmbeddingProvider = { id: string; user_id: string; /** * Team that owns this provider. */ team_id?: string | null; name: string; provider_type: string; /** * Embedding model this provider requests. Must return the fixed vector width VibeXP stores (1024). */ model: string; /** * In-Go text-chunker size used when embedding documents. */ chunk_size: number; /** * Overlap between adjacent chunks. */ chunk_overlap: number; /** * Maximum number of simultaneous embedding requests VibeXP issues to this provider. Keep at 1 for single-threaded providers. */ concurrency: number; /** * Instruction prefix prepended to search queries before they are embedded (only the text sent to the provider; nothing extra is stored). Asymmetric models require this — e.g. mxbai/BGE English expect "Represent this sentence for searching relevant passages: ", E5 expects "query: ". Empty/null means no prefix (default behaviour). */ query_prefix?: string | null; /** * Instruction prefix prepended to document chunks before they are embedded (applied only to the text sent to the provider; the stored chunk content is unchanged). E5 expects "passage: "; mxbai/BGE embed documents raw. Changing this invalidates stored vectors and triggers a team re-embed. Empty/null means no prefix (default behaviour). */ document_prefix?: string | null; is_default: boolean; base_url?: string | null; configuration: string; created_at: string; updated_at: string; /** * Optimistic-concurrency version counter, incremented on each update. Note: create responses currently return 0 (the persisted row starts at 1) — read it from get/list/update responses instead. */ version: number; }; export type EmbeddingProviderArrayResponse = Array; export type EmbeddingProviderResponse = EmbeddingProvider & { has_api_key: boolean; }; export type CreateEmbeddingProviderRequest = { name: string; provider_type: string; /** * Embedding model that must return 1024-dimensional vectors. */ model: string; /** * Optional chunker size; defaults to 1000 when omitted. */ chunk_size?: number; /** * Optional chunk overlap; defaults to 200 when omitted. */ chunk_overlap?: number; /** * Optional max simultaneous embedding requests to this provider; defaults to 1 when omitted. */ concurrency?: number; /** * Optional instruction prefix prepended to search queries before embedding. Defaults to empty (no prefix) when omitted. */ query_prefix?: string | null; /** * Optional instruction prefix prepended to document chunks before embedding. Defaults to empty (no prefix) when omitted. */ document_prefix?: string | null; is_default?: boolean; base_url?: string; api_key?: string | null; configuration?: { [key: string]: unknown; }; }; export type UpdateEmbeddingProviderRequest = { name?: string; provider_type?: string; model?: string; chunk_size?: number; chunk_overlap?: number; concurrency?: number; /** * Instruction prefix prepended to search queries before embedding. Send an empty string to clear a previously configured prefix. */ query_prefix?: string | null; /** * Instruction prefix prepended to document chunks before embedding. Changing it triggers a team re-embed. Send an empty string to clear. */ document_prefix?: string | null; is_default?: boolean; base_url?: string; api_key?: string; configuration?: { [key: string]: unknown; }; }; export type ValidateEmbeddingProviderRequest = { provider_type: string; /** * Embedding model to probe. The provider is accepted only if it returns vectors of the fixed dimension VibeXP stores (1024). */ model: string; base_url: string; api_key?: string | null; configuration?: { [key: string]: unknown; }; }; export type ValidateEmbeddingProviderResponse = { is_valid: boolean; message: string; details?: { response_time_ms?: number; status_code?: number; /** * Vector width the provider returned during the probe. */ dimension?: number; error_details?: string; }; }; /** * Embedding coverage for a single entity type: how many entities exist, how many have an embedding under the team's active model, how many are still pending, and the embedded percentage. */ export type EmbeddingCoverageItem = { /** * The embeddable entity type this row reports on. */ entity_type: 'prompt' | 'artifact' | 'memory' | 'blueprint' | 'feed_item'; /** * Total embeddable entities of this type owned by the team. */ total: number; /** * Entities of this type that already have an embedding under the team's active model. */ embedded: number; /** * Entities still missing an embedding (total − embedded). */ pending: number; /** * Rounded percentage of entities embedded (embedded / total * 100); 0 when there are no entities of this type. */ embedded_percent: number; }; /** * Derived, team-scoped embedding coverage per entity type under the team's active provider model. Counts are computed from existing rows (no per-entity state); a non-decreasing pending count is the signal that embedding is stuck. When the team has no active provider, has_active_provider is false, active_model is null, and every type reports all entities as pending (0%). */ export type EmbeddingCoverageResponse = { /** * Whether the team has an active embedding provider configured. */ has_active_provider: boolean; /** * The active provider's embedding model the embedded counts are measured against, or null when no provider is configured. */ active_model: string | null; /** * One entry per embeddable entity type, in a stable order. */ coverage: Array; }; /** * Result of clearing (truncating) all of a team's stored embeddings. Reports how many embedding rows were removed. Clearing does not regenerate anything — the team's content stays unembedded (and semantic search returns nothing for it) until a provider reprocess/re-embed runs. */ export type ClearEmbeddingsResponse = { /** * Number of embedding rows deleted for the team (0 if there were none). */ deleted_count: number; }; /** * Request body for copying one embedding provider out of another team into this one (#831, epic #827). The destination is the `{team_id}` path parameter; only the source is carried here. * * The API key is deliberately absent. Responses expose `has_api_key` and never the key itself, so a client cannot carry the credential across — the server re-reads the source row's stored ciphertext and writes it to the copy untouched, without ever decrypting it. * * Every property other than the two source identifiers and `reprocess` is an OPTIONAL override of the value the source row already holds: omit one to copy the source value verbatim, or send it to change the copy without touching the source. An override that IS sent must be non-empty, the same bar the create path sets. * * The copy is always written non-default. It can still become the team's ACTIVE embedding provider — see `EmbeddingProviderCopyActivation` on the response. * */ export type CopyEmbeddingProviderRequest = { /** * Team to copy the provider from. The caller needs permission to manage provider settings in it, and it must differ from the destination team. * */ source_team_id: string; /** * Provider to copy, as it exists in the source team. */ source_provider_id: string; /** * Name for the copy. Sent, it is used verbatim, and a name the destination already holds fails the copy with 409. Omitted, the source name is used, disambiguated as " (copy)", " (copy 2)", … when the destination already holds it. * */ name?: string; /** * Overrides the source provider's type. */ provider_type?: string; /** * Overrides the source provider's embedding model. It must return the fixed vector width VibeXP stores (1024); this endpoint does not probe it, so validate the model first if you override it. * */ model?: string; /** * Overrides the source provider's base URL. Send null or an empty string to store no base URL on the copy. * */ base_url?: string | null; /** * Overrides the source provider's chunk size. */ chunk_size?: number; /** * Overrides the source provider's chunk overlap. */ chunk_overlap?: number; /** * Overrides the source provider's embedding request concurrency. */ concurrency?: number; /** * Overrides the source provider's query instruction prefix. Send null or an empty string to store no prefix on the copy. * */ query_prefix?: string | null; /** * Overrides the source provider's document instruction prefix. Send null or an empty string to store no prefix on the copy. * */ document_prefix?: string | null; /** * Overrides the source provider's stored configuration object. */ configuration?: { [key: string]: unknown; }; /** * Opt in to re-embedding the destination team's content after the copy. * * Omitted or false, nothing is enqueued and the response's `activation.reprocess_enqueued` is false. Sent true, a background re-embed is enqueued for the destination team, and the response reports whether the team's existing vectors were WIPED first: they are, and only are, when the copy becomes the effective active provider AND its model differs from the model it displaces — the case where the stored vectors can no longer be compared against new queries. Any other case fills gaps only, leaving stored vectors intact. * */ reprocess?: boolean; }; /** * What the copy did to the destination team's SEARCH behaviour (#831). * * A copy is always written `is_default: false`, but that is not the same as inert. The active provider is resolved as "the default-flagged one, else the most recently updated one", so a non-default copy silently becomes the team's active provider whenever the destination has no default set — and every resource already embedded with the previous model stops being comparable to new queries, with no error anywhere. This object reports that verdict so a client can warn before, or explain after. * */ export type EmbeddingProviderCopyActivation = { /** * True when the copy is now the team's effective active embedding provider — the one that will generate every new document and query embedding. * */ becomes_active: boolean; /** * The embedding model that WAS active in the destination team before this copy, when the copy displaced it. Null when the copy did not become active, or when the team had no provider at all. * * It may equal the copy's own model: copying a provider that only differs in credentials or base URL displaces nothing meaningful, and the stored vectors stay valid. * */ displaced_model: string | null; /** * How many of the destination team's resources are embedded with `displaced_model`. These are the vectors that stop matching new queries unless the team re-embeds. 0 when nothing was displaced. * */ displaced_embedded_resources: number; /** * True when the request's `reprocess` flag actually started a background re-embed for the destination team. * * It reports what happened, not what was asked for: a re-embed already in flight for the team makes this false (the running one covers the work), and so does a failed wipe, which abandons the run rather than regenerating on top of stale vectors. * */ reprocess_enqueued: boolean; /** * True when the enqueued re-embed DELETED the team's stored vectors before regenerating them. Only ever true alongside `reprocess_enqueued`, and only when the copy became active with a different model from the one it displaced. * */ embeddings_wiped: boolean; }; /** * The provider row created by a cross-team copy, plus the activation verdict that says what it did to the destination team's search (#831). * */ export type CopyEmbeddingProviderResponse = { provider: EmbeddingProviderResponse; activation: EmbeddingProviderCopyActivation; }; export type ModelProvider = { id: string; user_id: string; /** * Team that owns this provider. */ team_id?: string | null; name: string; provider_type: string; /** * Chat/completion model this provider requests. */ model: string; is_default: boolean; base_url?: string | null; configuration: string; created_at: string; updated_at: string; /** * Optimistic-concurrency version counter, incremented on each update. Note: create responses currently return 0 (the persisted row starts at 1) — read it from get/list/update responses instead. */ version: number; }; export type ModelProviderResponse = ModelProvider & { has_api_key: boolean; }; export type CreateModelProviderRequest = { name: string; provider_type: string; /** * Chat/completion model to use. */ model: string; is_default?: boolean; base_url?: string; api_key?: string | null; configuration?: { [key: string]: unknown; }; }; export type UpdateModelProviderRequest = { name?: string; provider_type?: string; model?: string; is_default?: boolean; base_url?: string; api_key?: string; configuration?: { [key: string]: unknown; }; }; export type ModelProviderListResponse = { model_providers: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type ModelProviderResponseList = Array; /** * Request body for copying one model provider out of another team into this one. The destination is the `{team_id}` path parameter; only the source is carried here. * * The API key is deliberately absent. Responses expose `has_api_key` and never the key itself, so a client cannot carry the credential across — the server re-reads the source row's stored ciphertext and writes it to the copy untouched, without ever decrypting it. * * Every property other than the two source identifiers is an OPTIONAL override of the value the source row already holds: omit one to copy the source value verbatim, or send it to change the copy without touching the source. An override that IS sent must be non-empty, the same bar the create path sets. * */ export type CopyModelProviderRequest = { /** * Team to copy the provider from. The caller needs permission to manage provider settings in it, and it must differ from the destination team. * */ source_team_id: string; /** * Provider to copy, as it exists in the source team. */ source_provider_id: string; /** * Name for the copy. Sent, it is used verbatim, and a name the destination already holds fails the copy with 409. Omitted, the source name is used, disambiguated as " (copy)", " (copy 2)", … when the destination already holds it. * */ name?: string; /** * Overrides the source provider's type. */ provider_type?: string; /** * Overrides the source provider's chat/completion model. */ model?: string; /** * Overrides the source provider's base URL. Send null or an empty string to store no base URL at all. * */ base_url?: string | null; /** * Overrides the source provider's configuration wholesale. */ configuration?: { [key: string]: unknown; }; }; export type ValidateModelProviderRequest = { provider_type: string; /** * Chat/completion model to probe for reachability and auth. */ model: string; base_url: string; api_key?: string | null; configuration?: { [key: string]: unknown; }; }; export type ValidateModelProviderResponse = { is_valid: boolean; message: string; details?: { response_time_ms?: number; status_code?: number; error_details?: string; }; }; /** * A team's own GitHub App registration. Never carries secret values. */ export type GitHubAppConfig = { id: string; /** * Team that owns this App registration. */ team_id: string; /** * Who registered the App. Informational only — the team is the tenancy boundary, and no read is scoped by this field. */ user_id?: string | null; /** * GitHub's numeric App id, carried as a string. */ app_id: string; /** * The App's slug, which builds its install URL (https://github.com/apps/{app_slug}/installations/new). */ app_slug: string; /** * The App's OAuth client id. Not a secret — GitHub shows it on the App settings page, and it is echoed back so an operator can confirm which App is wired up. */ client_id: string; created_at: string; updated_at: string; /** * Optimistic-concurrency version counter, incremented on each update. */ version: number; }; /** * The App registration as returned by every read. Secrets are replaced by has_* booleans; webhook_url is the URL to paste into the App's settings. */ export type GitHubAppConfigResponse = GitHubAppConfig & { /** * Whether a private key is stored. The key itself is never returned. */ has_private_key: boolean; /** * Whether a client secret is stored. The secret itself is never returned. */ has_client_secret: boolean; /** * Whether a webhook secret is stored. The secret is disclosed only once, when it is generated; recovering a lost one means rotating it. */ has_webhook_secret: boolean; /** * The webhook URL for this App, carrying its opaque routing token. Paste it into the App's settings on GitHub. Empty when the instance has no public base URL configured. */ webhook_url: string; }; /** * The one and only payload that carries a plaintext webhook secret. Returned by create and by webhook-secret rotation; every subsequent read returns GitHubAppConfigResponse, which cannot carry it. */ export type CreateGitHubAppConfigResponse = GitHubAppConfigResponse & { /** * The generated webhook secret, shown exactly once. Paste it into the App's settings alongside the webhook URL; it cannot be read back. */ webhook_secret: string; }; /** * Registers a team's GitHub App. There is deliberately no webhook_secret field — the server generates it and returns it once. */ export type CreateGitHubAppConfigRequest = { /** * GitHub's numeric App id. */ app_id: string; /** * The App's slug, used to build its install URL. */ app_slug: string; /** * The App's OAuth client id. */ client_id: string; /** * The App's RSA private key, as raw PEM or base64-encoded PEM. Encrypted at rest and never returned. */ private_key: string; /** * The App's OAuth client secret. Encrypted at rest and never returned. */ client_secret: string; }; /** * Edits the team's App registration. Every field is optional; an omitted field keeps the stored value. An explicitly EMPTY value is rejected rather than treated as a clear — a GitHub App with no private key is not a meaningful state, so a blank value is far more likely a client bug than an intent. webhook_secret is absent for the same reason it is absent from create: it is server-generated, and replaced through the rotation endpoint. */ export type UpdateGitHubAppConfigRequest = { app_id?: string; app_slug?: string; client_id?: string; /** * Replacement RSA private key (raw PEM or base64-encoded PEM). */ private_key?: string; /** * Replacement OAuth client secret. */ client_secret?: string; }; /** * Result of probing GitHub with the stored credentials. A failed probe is reported here with is_valid=false, not as an HTTP error — a wrong key is user-correctable, not a server fault. error_details is always one of a fixed set of categories so the response cannot become an oracle for what the server could reach; the real upstream error is logged server-side only. */ export type ValidateGitHubAppConfigResponse = { is_valid: boolean; /** * Human-readable summary of the outcome. */ message: string; /** * The slug GitHub reports for the authenticated App, echoed so a mismatch with the stored value is visible rather than silently producing a broken install URL later. */ app_slug?: string; /** * The App's granted permissions, so a missing contents/metadata read can be surfaced before it breaks an import. */ permissions?: { [key: string]: string; }; details?: ValidateGitHubAppConfigDetails; }; /** * Fixed-category diagnostics for a validation probe. */ export type ValidateGitHubAppConfigDetails = { response_time_ms?: number; /** * HTTP status GitHub returned, when the probe got that far. */ status_code?: number; /** * Fixed failure category. Never carries upstream error text, which would reveal what the server could and could not reach. */ error_details?: 'invalid_credentials' | 'app_not_found' | 'slug_mismatch' | 'insufficient_permissions' | 'connection_failed'; }; /** * Non-secret SMTP settings. The password is the provider's secret. */ export type SmtpProviderSettings = { /** * SMTP server hostname. */ host: string; /** * SMTP port, as a string. Must parse to 1-65535. */ port: string; /** * SMTP username, when the server requires authentication. */ username?: string; }; /** * Non-secret Mailgun settings. The sending key is the provider's secret. */ export type MailgunProviderSettings = { /** * The Mailgun sending domain. Must be a bare domain, not a URL. */ domain: string; /** * Optional API base URL, to select a non-US region (for example https://api.eu.mailgun.net/v3). A missing /v2|/v3|/v4 suffix is normalised to /v3. */ base_url?: string; }; /** * Non-secret Postmark settings. The server token is the provider's secret. */ export type PostmarkProviderSettings = { /** * Postmark message stream to send on. Defaults to "outbound", the default transactional stream. */ message_stream?: string; }; /** * Per-type non-secret settings. Exactly the block matching `provider_type` may be present; a block belonging to another type is rejected rather than ignored. SendGrid has no block — its only configuration is its API key, which is the secret. */ export type TeamEmailProviderSettings = { smtp?: SmtpProviderSettings; mailgun?: MailgunProviderSettings; postmark?: PostmarkProviderSettings; }; /** * The team's email provider configuration. This is an upsert, so the same body creates or replaces. */ export type UpsertTeamEmailProviderRequest = { /** * Which provider to send through. Matched case-insensitively. */ provider_type: 'smtp' | 'mailgun' | 'postmark' | 'sendgrid'; settings?: TeamEmailProviderSettings; /** * The provider's single credential (SMTP password, Mailgun sending key, Postmark server token, or SendGrid API key). Required when configuring a provider for the first time. * On a team that already has a provider, OMIT this field to keep the stored credential — it is never returned, so a client cannot resend it. An explicitly empty string is rejected: a provider with no credential cannot send, so clearing it would silently disable the team's mail. */ secret?: string; /** * The address the team's mail is sent from. */ from_address: string; /** * Optional display name shown beside the from address. */ from_name?: string | null; /** * Optional Reply-To address. */ reply_to?: string | null; }; /** * The email configuration in force for a team — its own provider, or the instance provider it inherits. This is never a 404: a team without its own provider is inheriting one, which is a state the caller needs described. * No field here can carry the credential; `has_credential` reports only that one is stored. */ export type TeamEmailProviderResponse = { /** * Whether the team has its own provider configured. */ configured: boolean; /** * Which provider will actually send: the team's own, or the instance provider from the deployment configuration. */ source: 'team' | 'instance'; /** * The address mail will actually be sent from — the team's when configured, otherwise the instance's. */ effective_from_address: string; /** * The team's provider type, or null when the team inherits the instance provider. */ provider_type: 'smtp' | 'mailgun' | 'postmark' | 'sendgrid' | null; /** * Whether a credential is stored for the team's provider. The credential itself is never returned. */ has_credential: boolean; /** * The team's configured from address. Absent when inheriting the instance provider. */ from_address?: string; /** * The team's configured display name. */ from_name?: string | null; /** * The team's configured Reply-To address. */ reply_to?: string | null; settings?: TeamEmailProviderSettings; /** * Whether the last observed send succeeded. Derived by comparing last_success_at with last_error_at, so a recovered provider is healthy even though last_error is still populated. */ is_healthy?: boolean; /** * When a send through the team's provider last succeeded. */ last_success_at?: string | null; /** * The last delivery error. Deliberately retained after recovery for diagnosis, so its presence alone does not mean the provider is broken — use is_healthy. */ last_error?: string | null; /** * When the last delivery error occurred. */ last_error_at?: string | null; }; /** * Fixed-category detail for a failed test send. The real upstream error is logged server-side only. */ export type TeamEmailProviderTestDetails = { /** * Why the test failed: `configuration_invalid` when the provider could not be built at all (nothing was dialled), `send_failed` when it was built but delivery failed. Absent on success. */ error_details?: 'configuration_invalid' | 'send_failed'; }; /** * Outcome of a test send. A failed send is reported here with `is_valid: false`, not as an HTTP error — the caller asked whether the configuration works, and "no, because X" is a successful answer. */ export type TeamEmailProviderTestResponse = { /** * Whether the test message was accepted by the provider. */ is_valid: boolean; /** * Human-readable outcome, safe to show to an admin. */ message: string; /** * Where the test message was sent. Always the acting user's own account email — this endpoint never accepts a caller-supplied recipient, so it cannot be used to send mail to third parties. */ recipient: string; details: TeamEmailProviderTestDetails; }; export type SupportRequest = { text: string; additional_info?: { [key: string]: string; }; /** * Whether to send an acknowledgement email to the user */ acknowledgement?: boolean; }; export type SupportResponse = { message: string; success: boolean; }; export type Artifact = { /** * Unique identifier for the artifact */ id: string; /** * UUID of the project this artifact belongs to */ project_id: string; /** * Unique slug for the artifact within the project */ slug: string; /** * ID of the user who owns this artifact */ user_id: string; /** * The actual content of the artifact */ content?: string; /** * Timestamp when the artifact was created */ created_at: string; /** * Timestamp when the artifact was last updated */ updated_at: string; /** * Current status of the artifact */ status: 'active' | 'draft' | 'archived'; /** * Human-readable title for the artifact */ title: string; /** * Optional description of the artifact */ description?: string; /** * Type category of the artifact. An open string validated at runtime against the team's registered types (the system defaults work_reports, static_contexts and general, plus any custom types the team has added), not a fixed enum. */ type: string; /** * Additional metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; /** * Depth-1 typed neighborhood of this resource — the relations touching it in both directions, newest first, capped at 20. Typed summaries only, never bodies. Populated on the detail GET; empty in list responses. */ related?: Array; /** * Computed embedding-similarity neighborhood of this resource (up to 5), derived live at read time from vector similarity — NOT stored edges and distinct from `related`. Populated on the detail GET; empty otherwise. */ similar?: Array; freshness?: ResourceFreshnessState; }; export type CreateArtifactRequest = { /** * UUID of the project this artifact belongs to */ project_id: string; /** * Unique slug for the artifact within the project */ slug: string; /** * The actual content of the artifact */ content: string; /** * Human-readable title for the artifact */ title: string; /** * Optional description of the artifact */ description?: string; /** * Type category of the artifact. An open string validated at runtime against the team's registered types (the system defaults work_reports, static_contexts and general, plus any custom types the team has added), not a fixed enum. Defaults to general when omitted. */ type?: string; /** * Initial status of the artifact */ status?: 'active' | 'draft' | 'archived'; /** * Additional metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; }; export type UpdateArtifactRequest = { /** * New project UUID for the artifact */ project_id?: string; /** * New slug for the artifact */ slug?: string; /** * Updated content of the artifact */ content?: string; /** * Updated title for the artifact */ title?: string; /** * Updated description of the artifact */ description?: string; /** * Updated type category of the artifact. An open string validated at runtime against the team's registered types (the system defaults work_reports, static_contexts and general, plus any custom types the team has added), not a fixed enum. */ type?: string; /** * Updated status of the artifact */ status?: 'active' | 'draft' | 'archived'; /** * Updated metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; /** * Optional human-readable summary of this edit, recorded on the content-version snapshot it produces and shown in the version history. */ change_summary?: string; }; export type ArtifactListResponse = { /** * List of artifacts */ artifacts: Array; /** * Total number of artifacts matching the filter criteria */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type ArtifactStatsResponse = { /** * Total number of projects with artifacts */ total_projects: number; /** * Total number of artifacts */ total_artifacts: number; /** * Number of artifacts added in the current week */ added_this_week: number; /** * Count of artifacts by type */ total_by_type: { [key: string]: number; }; /** * Count of artifacts by status */ total_by_status: { [key: string]: number; }; }; export type Attachment = { /** * Unique identifier for the attachment */ id: string; /** * Team that owns the attachment */ team_id: string; /** * ID of the user who uploaded the attachment; omitted if that user was deleted */ user_id?: string; /** * Polymorphic owner type (currently always "artifact") */ owner_type: string; /** * ID of the owning resource (e.g. the artifact) */ owner_id: string; /** * Original file name (basename only) */ file_name: string; /** * Optional path relative to the owner's directory (e.g. "scripts/helper.py" for a multi-file skill companion). Absent for a plain attachment. Unique per owner. */ relative_path?: string; /** * Canonical content type of the file */ content_type: string; /** * Size of the file in bytes */ size_bytes: number; /** * Timestamp when the attachment was uploaded */ created_at: string; }; export type AttachmentListResponse = { /** * List of attachments for the owner, newest first */ attachments: Array; /** * Number of attachments */ total_count: number; /** * Combined size of all attachments in bytes */ total_size_bytes: number; }; export type ContentVersion = { /** * Unique identifier for the version snapshot */ id: string; /** * Team that owns the versioned resource */ team_id: string; /** * Type of the versioned resource */ resource_type: string; /** * ID of the resource this snapshot belongs to */ resource_id: string; /** * Monotonic per-resource version number */ version_number: number; /** * Snapshot of the resource content at this version */ content: string; /** * Human-readable summary of the change captured at this version (the "commit message"). Null when none was recorded; the first version defaults to a resource-specific creation label (e.g. "Created the artifact"). */ change_summary: string | null; /** * Who authored this version: 'human' for a user edit, 'system' for a system-generated version such as a restore. */ actor_type: 'human' | 'system'; /** * User who triggered the snapshot; null when that user is later deleted */ created_by: string | null; author: VersionAuthor; /** * Timestamp when the snapshot was created */ created_at: string; }; export type ArtifactVersionListResponse = { /** * Content-version snapshots for the artifact, newest first */ versions: Array; }; export type Feed = { /** * Unique identifier for the feed */ id: string; /** * UUID of the team this feed belongs to */ team_id: string; /** * Human-readable name for the feed */ name: string; /** * Optional description of the feed */ description?: string | null; /** * ID of the user who created this feed */ created_by_user_id: string; /** * Timestamp when the feed was created */ created_at: string; /** * Timestamp when the feed was last updated */ updated_at: string; }; export type FeedItem = { /** * Unique identifier for the feed item */ id: string; /** * UUID of the team this item belongs to */ team_id: string; /** * UUID of the feed this item belongs to */ feed_id: string; /** * Optional UUID of the associated project */ project_id?: string | null; /** * Title of the feed item */ title: string; /** * Full content of the feed item (max 200 KB) */ content: string; /** * Server-computed plain-text excerpt (first 300 chars, markdown stripped) */ excerpt: string; /** * Name of the AI assistant that generated this item */ ai_assistant_name: string; /** * ID of the user who posted this item */ posted_by_user_id: string; /** * Timestamp when the item was archived, null if active */ archived_at?: string | null; /** * Server-set timestamp when the item was posted */ posted_at: string; /** * Number of replies to this item. Populated with the real count on list and single-item GET responses; always 0 on create responses (a new item has no replies yet). */ reply_count: number; }; export type CreateFeedRequest = { /** * Name of the feed (unique within the team) */ name: string; /** * Optional description of the feed */ description?: string; }; export type UpdateFeedRequest = { /** * Updated name of the feed */ name?: string; /** * Updated description of the feed */ description?: string; }; export type CreateFeedItemRequest = { /** * Title of the feed item */ title: string; /** * Full content of the feed item (max 200 KB) */ content: string; /** * Name of the AI assistant that generated this item (no normalization applied) */ ai_assistant_name: string; /** * Optional UUID of the associated project (must belong to the same team) */ project_id?: string; }; export type FeedListResponse = { /** * List of feeds */ feeds: Array; /** * Total number of feeds matching the filter criteria */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type FeedItemListResponse = { /** * List of feed items */ items: Array; /** * Total number of items matching the filter criteria */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type GitHubImportProjectResultResponse = { project: Project; /** * Whether the project was created by this request (false when it already existed) */ created: boolean; message?: string; }; export type Project = { /** * Unique identifier for the project */ id: string; /** * ID of the user who created this project */ user_id: string; /** * ID of the team this project belongs to */ team_id: string; /** * Human-readable name of the project */ name: string; /** * Unique slug for the project (URL-friendly identifier) */ slug: string; /** * Optional description of the project (empty string when unset) */ description: string; /** * Git repository URL for the project (empty string when unset) */ git_url: string; /** * Homepage URL for the project (empty string when unset) */ homepage: string; /** * Timestamp when the project was created */ created_at: string; /** * Timestamp when the project was last updated */ updated_at: string; /** * Version number for optimistic locking */ version: number; }; export type CreateProjectRequest = { /** * Human-readable name of the project */ name: string; /** * Unique slug for the project (URL-friendly identifier) */ slug: string; /** * Optional team ID; defaults to the team from the URL path */ team_id?: string; /** * Optional description of the project */ description?: string; /** * Git repository URL for the project */ git_url?: string; /** * Homepage URL for the project */ homepage?: string; }; export type UpdateProjectRequest = { /** * Updated name of the project */ name?: string; /** * Updated slug for the project */ slug?: string; /** * Team ID; must match the project's current team (resources cannot be moved between teams) */ team_id?: string; /** * Updated description of the project */ description?: string; /** * Updated git repository URL */ git_url?: string; /** * Updated homepage URL */ homepage?: string; }; export type ProjectListResponse = { /** * List of projects with computed fields */ projects: Array; /** * Total number of projects matching the filter criteria */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type ProjectStatsResponse = { /** * Total number of prompts belonging to this project */ total_prompts?: number; /** * Total number of artifacts belonging to this project */ total_artifacts?: number; /** * Total number of spec libraries belonging to this project */ total_blueprints?: number; /** * Total number of memories belonging to this project */ total_memories?: number; /** * Total number of feed items belonging to this project */ total_feed_items?: number; }; export type ProjectResourceCreationMetricsResponse = { status: string; message: string; data: ProjectResourceCreationMetricsData; }; export type Memory = { /** * Unique identifier for the memory */ id: string; /** * ID of the user who owns this memory */ user_id: string; /** * ID of the team this memory belongs to */ team_id: string; /** * ID of the project this memory belongs to */ project_id: string; /** * The text content of the memory */ text: string; /** * Current lifecycle status of the memory */ status: 'active' | 'draft' | 'archived'; /** * Additional metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; /** * Timestamp when the memory was created */ created_at: string; /** * Timestamp when the memory was last updated */ updated_at: string; /** * Version number for optimistic concurrency control */ version: number; /** * Depth-1 typed neighborhood of this resource — the relations touching it in both directions, newest first, capped at 20. Typed summaries only, never bodies. Populated on the detail GET; empty in list responses. */ related?: Array; /** * Computed embedding-similarity neighborhood of this resource (up to 5), derived live at read time from vector similarity — NOT stored edges and distinct from `related`. Populated on the detail GET; empty otherwise. */ similar?: Array; freshness?: ResourceFreshnessState; }; export type CreateMemoryRequest = { /** * UUID of the project this memory belongs to */ project_id: string; /** * The text content of the memory */ text: string; /** * Initial lifecycle status of the memory (defaults to active) */ status?: 'active' | 'draft' | 'archived'; /** * Additional metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; }; export type UpdateMemoryRequest = { /** * New project UUID for the memory (moves it between projects) */ project_id?: string; /** * Updated text content of the memory */ text?: string; /** * Updated lifecycle status of the memory */ status?: 'active' | 'draft' | 'archived'; /** * Updated metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; }; export type MemoryListResponse = { /** * List of memories */ memories: Array; /** * Total number of memories matching the filter criteria */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type MemoryVersionListResponse = { /** * Content-version snapshots for the memory, newest first */ versions: Array; }; export type SearchRequest = { /** * Free-text query to embed and search semantically */ query: string; /** * Resource types to search. Omit or leave empty to search all four types. Unknown values are rejected with a 400. */ types?: Array<'prompts' | 'artifacts' | 'blueprints' | 'memories'>; /** * Optional project UUID. When set, results are restricted to this project across every type. Omit to search across all projects. */ project_id?: string; /** * Page number */ page?: number; /** * Number of items per page */ per_page?: number; }; export type SearchResultItem = { /** * Singular resource type of the matched source entity */ type: 'prompt' | 'artifact' | 'blueprint' | 'memory'; /** * ID of the source resource the matched chunk belongs to */ id: string; /** * Title of the source resource */ title: string; /** * Slug of the source resource, used to build slug-based detail-page links. Empty for memories, which are routed by id. */ slug: string; /** * UUID of the parent project. Used to build artifact and blueprint detail-page links, which are keyed by project UUID. Always present — every resource belongs to exactly one project. */ project_id: string; /** * Human-readable name of the parent project, shown alongside each result. */ project_name: string; /** * Matched chunk content, truncated to at most 500 characters */ excerpt: string; /** * Relevance score (1 - cosine distance), clamped to [0,1] */ score: number; /** * ID of the matched embedding row (chunk) */ chunk_id: string; /** * Last-updated timestamp of the source resource */ updated_at: string; }; export type SearchResultsResponse = { /** * Relevance-ranked search results, one per matching entity (carrying its best-scoring chunk) */ results: Array; /** * Total number of matching resources (distinct entities) across all pages */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type Blueprint = { /** * Unique identifier for the spec library */ id: string; /** * UUID of the project this spec library belongs to */ project_id: string; /** * Unique slug for the spec library within the project */ slug: string; /** * ID of the user who owns this spec library */ user_id: string; /** * The actual content/specification of the spec library */ content: string; /** * Timestamp when the spec library was created */ created_at: string; /** * Timestamp when the spec library was last updated */ updated_at: string; /** * Current status of the spec library */ status: 'active' | 'expired'; /** * Human-readable title for the spec library */ title: string; /** * Optional description of the spec library */ description?: string; /** * Type category of the spec library */ type: 'general' | 'claude-code' | 'claude' | 'cursor' | 'codex'; /** * Subtype category for specific type spec libraries */ subtype?: 'sub-agents' | 'skills' | 'slash-commands' | 'others' | 'claude-md' | 'agents' | 'commands' | 'rules' | 'cursor-md' | 'agents-md'; /** * Additional metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; /** * Canonical repo-relative path this blueprint materializes to. Derived from (type, subtype, slug) for VibeXP-authored blueprints, or the verbatim source path for imported ones. */ path: string; /** * SHA-256 (lowercase hex) of the raw content. */ content_sha?: string; source?: BlueprintSource; /** * Depth-1 typed neighborhood of this resource — the relations touching it in both directions, newest first, capped at 20. Typed summaries only, never bodies. Populated on the detail GET; empty in list responses. */ related?: Array; /** * Computed embedding-similarity neighborhood of this resource (up to 5), derived live at read time from vector similarity — NOT stored edges and distinct from `related`. Populated on the detail GET; empty otherwise. */ similar?: Array; freshness?: ResourceFreshnessState; }; /** * Read-only import provenance; present only for imported blueprints. */ export type BlueprintSource = { /** * Source repository URL the blueprint was imported from. */ repo?: string; /** * Head commit SHA of the branch at import time. */ commit_sha?: string; /** * Git blob SHA of the source file at import time. */ blob_sha?: string; /** * Timestamp when the blueprint was imported. */ imported_at?: string; }; export type BlueprintDetail = Blueprint & { /** * Original raw bytes of the blueprint (frontmatter + body). Returned only on the detail GET, never in list responses. */ raw_content?: string; }; export type CreateBlueprintRequest = { /** * UUID of the project this spec library belongs to */ project_id?: string; /** * Unique slug for the spec library within the project */ slug: string; /** * The actual content/specification of the spec library */ content: string; /** * Human-readable title for the spec library */ title: string; /** * Optional description of the spec library */ description?: string; /** * Type category of the spec library */ type?: 'general' | 'claude-code' | 'claude' | 'cursor' | 'codex'; /** * Subtype category for specific type spec libraries */ subtype?: 'sub-agents' | 'skills' | 'slash-commands' | 'others' | 'claude-md' | 'agents' | 'commands' | 'rules' | 'cursor-md' | 'agents-md'; /** * Initial status of the spec library */ status?: 'active' | 'expired'; /** * Additional metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; /** * Optional repo-relative path to freeze for this blueprint. When omitted a default is derived from (type, subtype, slug). Must be relative — no leading "/", no "..", no backslashes. */ path?: string; }; export type UpdateBlueprintRequest = { /** * New project UUID for the spec library */ project_id?: string; /** * New slug for the spec library */ slug?: string; /** * Updated content/specification of the spec library */ content?: string; /** * Updated title for the spec library */ title?: string; /** * Updated description of the spec library */ description?: string; /** * Updated type category of the spec library */ type?: 'general' | 'claude-code' | 'claude' | 'cursor' | 'codex'; /** * Updated subtype category for specific type spec libraries */ subtype?: 'sub-agents' | 'skills' | 'slash-commands' | 'others' | 'claude-md' | 'agents' | 'commands' | 'rules' | 'cursor-md' | 'agents-md'; /** * Updated status of the spec library */ status?: 'active' | 'expired'; /** * Updated metadata as key-value pairs */ metadata?: { [key: string]: unknown; }; /** * Optional repo-relative path override; freezes the blueprint's path. Must be relative — no leading "/", no "..", no backslashes. */ path?: string; }; export type BlueprintListResponse = { /** * List of spec libraries */ blueprints: Array; /** * Total number of spec libraries matching the filter criteria */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type BlueprintStatsResponse = { /** * Total number of projects with spec libraries */ total_projects: number; /** * Total number of blueprints */ total_blueprints: number; /** * Number of spec libraries added in the current week */ added_this_week: number; /** * Count of spec libraries by type */ total_by_type: { [key: string]: number; }; /** * Count of spec libraries by status */ total_by_status: { [key: string]: number; }; }; export type BlueprintVersionListResponse = { /** * Content-version snapshots for the blueprint, newest first */ versions: Array; }; /** * Status of the GitHub App installation for a team */ export type GitHubInstallationStatus = { /** * Whether the GitHub App is installed for the team */ installed: boolean; /** * GitHub account or organization login that installed the app (present when installed is true) */ account_login?: string; /** * GitHub installation ID (present when installed is true) */ installation_id?: number; /** * Whether the installation is currently suspended */ suspended?: boolean; /** * When the GitHub App was installed (present when installed is true) */ installed_at?: string; }; /** * A GitHub repository accessible by the installation */ export type GitHubRepository = { /** * GitHub repository ID */ id: number; /** * Repository name (without owner) */ name: string; /** * Full repository name including owner (owner/repo) */ full_name: string; /** * Repository description */ description?: string | null; /** * Whether the repository is private */ private: boolean; /** * GitHub web URL for the repository */ html_url: string; /** * Repository owner information */ owner: { /** * Owner's GitHub login */ login: string; /** * Owner type (User or Organization) */ type: 'User' | 'Organization'; }; /** * Slug of the existing VibeXP project imported from this repository (when the repo's html_url matches an existing project's git_url within the team). Omitted/empty when no matching project exists. */ imported_project_slug?: string; }; /** * Paginated list of GitHub repositories accessible by the installation */ export type GitHubRepositoriesResponse = { /** * List of repositories for the current page */ repositories: Array; /** * Total number of repositories accessible by the installation */ total_count: number; /** * Current page number (1-based) */ page: number; /** * Number of items per page */ per_page: number; }; /** * Response returned after successfully completing the GitHub App installation callback */ export type GitHubCallbackResponse = { /** * Whether this was a reconnection to an existing installation (true) or a new installation (false) */ reconnected: boolean; }; /** * GitHub App installation URL with CSRF protection state parameter */ export type GitHubInstallUrl = { /** * URL to redirect the user to for installing the GitHub App */ install_url: string; }; /** * Details of a file that failed to be imported as a blueprint */ export type BlueprintImportFailed = { /** * Path of the file that failed to import */ file_path: string; /** * Generic error message (internal details are not exposed) */ error: string; }; /** * Details of a file successfully imported as a blueprint */ export type BlueprintImportSuccess = { /** * Path of the file that was imported */ file_path: string; /** * ID of the created blueprint */ blueprint_id: string; /** * Title of the created blueprint */ title: string; /** * Blueprint type */ type: string; /** * Blueprint subtype */ subtype?: string; }; /** * Details of a file that was skipped during blueprint import */ export type BlueprintImportSkipped = { /** * Path of the file that was skipped */ file_path: string; /** * Human-readable reason why the file was skipped */ reason: string; }; /** * Summary report of a blueprint import operation */ export type BlueprintImportReport = { /** * Total number of files scanned during the import */ total_scanned: number; /** * Number of files successfully imported as blueprints */ total_successful: number; /** * Number of files that failed to import */ total_failed: number; /** * Number of files skipped (non-markdown, empty, too large, or already exists) */ total_skipped: number; /** * Details of files that failed to import */ failed_items: Array; /** * Details of files successfully imported */ successful_items: Array; /** * Details of files that were skipped */ skipped_items: Array; /** * Number of blueprints refreshed from a changed repo file (unedited in VibeXP) */ total_updated: number; /** * Number of blueprints left untouched because they were edited in VibeXP */ total_conflicts: number; /** * Number of blueprints whose repo file was unchanged (no-op) */ total_up_to_date: number; /** * Details of blueprints refreshed from a changed repo file */ updated_items: Array; /** * Details of blueprints left untouched due to a VibeXP edit */ conflict_items: Array; /** * Details of blueprints whose repo file was unchanged */ up_to_date_items: Array; /** * Number of Agent Skill companion files stored as attachments (newly imported or replaced on re-import) */ total_companions_imported: number; /** * Number of companion files deleted during re-import reconciliation (absent from the re-imported skill) */ total_companions_removed: number; /** * Number of companion files rejected by the attachment service (oversized, over the per-owner budget, disallowed type, or storage unconfigured) */ total_companions_skipped: number; /** * Per-file outcomes for Agent Skill companion files, distinct from the blueprint (SKILL.md) outcomes */ companion_items: Array; }; /** * A blueprint refreshed from a changed repo file during re-import */ export type BlueprintImportUpdated = { file_path: string; blueprint_id: string; title: string; type: string; subtype?: string; }; /** * A blueprint left untouched during re-import because it was edited in VibeXP */ export type BlueprintImportConflict = { file_path: string; blueprint_id: string; reason: string; }; /** * A blueprint whose repo file was unchanged since import (re-import no-op) */ export type BlueprintImportUpToDate = { file_path: string; blueprint_id: string; }; /** * Per-file outcome of importing one Agent Skill companion file (a sibling of a SKILL.md) as a blueprint-owned attachment. */ export type BlueprintImportCompanion = { /** * ID of the blueprint (imported SKILL.md) that owns this companion */ blueprint_id: string; /** * Path of the companion file relative to the skill directory */ relative_path: string; /** * What happened to the companion file during import */ outcome: 'imported' | 'updated' | 'removed' | 'skipped'; /** * Why the companion was skipped (present only when outcome is "skipped") */ reason?: string; }; /** * Weekly usage metrics for a single week */ export type UsageMetricsRow = { /** * Week start date (Monday) */ week_start?: string; /** * Number of new users registered this week */ new_users?: number; /** * Number of new artifacts created this week */ new_artifacts?: number; /** * Number of new memories created this week */ new_memories?: number; /** * Number of new API keys created this week */ new_api_keys?: number; /** * Number of new prompts created this week */ new_prompts?: number; /** * Number of new agents created this week */ new_agents?: number; /** * Number of agent executions this week */ agent_executions?: number; }; /** * Per-user activity summary */ export type UserActivityRow = { /** * User ID */ user_id?: string; /** * User email */ email?: string; /** * User display name */ name?: string; /** * User registration timestamp */ user_created_at?: string; /** * Total number of artifacts created by user */ total_artifacts?: number; /** * Timestamp of first artifact creation */ first_artifact_created_at?: string | null; /** * Total number of memories created by user */ total_memories?: number; /** * Timestamp of first memory creation */ first_memory_created_at?: string | null; /** * Total number of prompts created by user */ total_prompts?: number; /** * Timestamp of first prompt creation */ first_prompt_created_at?: string | null; /** * Total number of agents created by user */ total_agents_created?: number; /** * Total number of agent executions run by user */ total_agent_executions_run?: number; }; /** * Usage and growth data response */ export type UsageAndGrowthResponse = { /** * Weekly usage metrics */ usage?: Array; /** * Per-user activity summary */ activities_per_user?: Array; }; /** * Information about the user who sent a team invitation */ export type InviterInfo = { id?: string; name?: string; email?: string; }; /** * Team invitation enriched with team and inviter details */ export type InvitationResponse = { id?: string; /** * Opaque invitation token used in invitation URLs */ token?: string; team_id?: string; team_name?: string; invitee_email?: string; role?: 'member' | 'admin'; status?: 'pending' | 'accepted' | 'rejected' | 'revoked'; expires_at?: string; created_at?: string; invited_by?: InviterInfo; }; /** * Bare list of team invitations returned by the list endpoint. */ export type InvitationResponseList = Array; /** * Wrapper response for the get-invitation-by-token endpoint */ export type InvitationDetailsResponse = { invitation: InvitationResponse; }; /** * A2A (Agent-to-Agent) protocol agent card (protocol v1.0), mirroring the official a2a-go SDK's a2a.AgentCard type. */ export type AgentCard = { name?: string; description?: string; version?: string; /** * Supported transport/protocol/URL combinations for interacting with the agent. */ supportedInterfaces?: Array<{ url?: string; /** * Transport protocol available at this URL (e.g. JSONRPC, GRPC, HTTP+JSON). */ protocolBinding?: string; protocolVersion?: string; tenant?: string | null; }> | null; defaultInputModes?: Array | null; defaultOutputModes?: Array | null; iconUrl?: string | null; documentationUrl?: string | null; provider?: { organization?: string; url?: string; } | null; capabilities?: { streaming?: boolean; pushNotifications?: boolean; extendedAgentCard?: boolean; extensions?: Array<{ uri?: string; description?: string; required?: boolean; params?: { [key: string]: unknown; } | null; }> | null; }; skills?: Array<{ id?: string; name?: string; description?: string; tags?: Array | null; examples?: Array | null; inputModes?: Array | null; outputModes?: Array | null; securityRequirements?: Array<{ [key: string]: unknown; }> | null; }> | null; /** * Security requirement options (OR of ANDs) applying to all agent interactions. */ securityRequirements?: Array<{ [key: string]: unknown; }> | null; /** * Security schemes available to authorize requests, keyed by scheme name. */ securitySchemes?: { [key: string]: { [key: string]: unknown; }; } | null; signatures?: Array<{ protected?: string; signature?: string; header?: { [key: string]: unknown; } | null; }> | null; }; export type UpdateAgentCredentialsRequest = { credentials: { [key: string]: CredentialRequest; }; }; export type PreviewAgentCardRequest = { /** * URL of the A2A agent card to fetch and preview */ card_url: string; }; export type ExecuteAgentRequest = { /** * Input payload forwarded to the agent */ input?: { [key: string]: unknown; }; /** * Existing conversation to continue; a new conversation is started when omitted */ conversation_id?: string | null; }; export type AgentExecutionListResponse = { executions: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type AgentExecutionEventsResponse = AgentExecutionEventsPollResponse | AgentExecutionEventsPageResponse; /** * Cursor-based polling response (returned when the `since` query parameter is provided) */ export type AgentExecutionEventsPollResponse = { execution_id: string; status: 'running' | 'success' | 'error' | 'pending' | 'submitted' | 'working' | 'completed' | 'failed' | 'cancelled'; current_state?: string | null; events: Array; /** * True while the execution is still pending or running */ has_more: boolean; /** * Pass as `since` on the next poll */ next_sequence: number; }; /** * Page-based pagination response (returned when the `since` query parameter is absent) */ export type AgentExecutionEventsPageResponse = { events: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type ConversationListResponse = { conversations: Array; total_count: number; page: number; per_page: number; total_pages: number; }; export type ConversationExecutionsResponse = { executions: Array; conversation_id: string; has_more: boolean; total_count: number; /** * Number of executions in this page */ count: number; }; /** * A team (workspace) in the system. `role`, `permissions` and `member_count` are computed at read time for the requesting user. */ export type Team = { id: string; /** * User ID of the team owner */ owner_id: string; name: string; slug: string; description: string; /** * Whether this is the user's personal workspace (cannot be deleted) */ is_personal: boolean; /** * The requesting user's role in this team: owner, admin, or member. Populated at runtime on every response that carries a team, including create (where the caller is by definition the owner). Not an enum constraint: older responses may still carry an empty string. */ role?: string; /** * Exactly what `role` permits the requesting user to do in this team, expanded server-side from the role matrix (epic #220). Clients MUST gate their UI on these strings rather than re-deriving them from `role` — the matrix lives on the server and may change without a client release. * Computed at read time for the requesting user, alongside `role`, and always present (an empty array means the role grants nothing). The values are stable API surface: renaming one is a breaking change, and they are kept byte-identical to the `internal/authz` constants by a drift test. Meanings: * * `team.update` — change team name, slug or description. * `team.delete` — delete the team (owner only). * `team.transfer` — transfer ownership to another member (owner only). * `team.settings.update` — change team-level configuration, such as search ranking. * `member.invite` — invite new members. * `member.remove` — remove members from the team. * `member.role.update` — change a member's role. * `project.create` — create a project in the team. * `project.update` — update any project in the team. * `project.delete` — delete any project in the team. * `resource.create` — create a prompt, memory, artifact, blueprint or agent. * `resource.update.any` — update any resource, including other members'. * `resource.delete.own` — delete a resource the caller created. * `resource.delete.any` — delete a resource created by someone else. * `feed.delete.any` — delete another member's feed post or reply (moderation). */ permissions: Array<'team.update' | 'team.delete' | 'team.transfer' | 'team.settings.update' | 'member.invite' | 'member.remove' | 'member.role.update' | 'project.create' | 'project.update' | 'project.delete' | 'resource.create' | 'resource.update.any' | 'resource.delete.own' | 'resource.delete.any' | 'feed.delete.any'>; /** * Number of members in this team. Populated only on list responses; 0 on create and single-team reads. */ member_count?: number; created_at: string; updated_at: string; }; /** * Request body for creating a team */ export type CreateTeamRequest = { /** * Team name (required, at most 100 characters) */ name: string; /** * Optional team description (at most 500 characters) */ description?: string; }; /** * Request body for updating a team. At least one of `name` or `description` must be provided. */ export type UpdateTeamRequest = { /** * New team name (must be non-empty when provided) */ name?: string; /** * New team description */ description?: string; }; /** * Paginated list of teams the user belongs to */ export type TeamListResponse = { teams: Array; total_count: number; page: number; page_size: number; }; /** * Detailed information about a team member, including invitation status */ export type TeamMemberDetail = { user_id: string; email: string; name: string; role: 'owner' | 'admin' | 'member'; /** * When the member joined the team */ joined_at: string; /** * Invitation status for this member (omitted when not applicable) */ invitation_status?: 'pending' | 'accepted'; }; /** * Request body for changing a team member's role. Only `member` and `admin` are * accepted: a team has exactly one owner, and ownership moves solely through * the transfer-ownership operation. * */ export type UpdateTeamMemberRoleRequest = { /** * The role to assign to the member */ role: 'member' | 'admin'; }; /** * The team member after the role change */ export type UpdateTeamMemberRoleResponse = { member: TeamMemberDetail; }; /** * Request body for transferring team ownership. The target must already be a * member of the team; they become the owner and the current owner becomes an * admin, in a single transaction. * */ export type TransferTeamOwnershipRequest = { /** * User ID of the member who will become the team owner */ new_owner_id: string; }; /** * The team after ownership has been transferred */ export type TransferTeamOwnershipResponse = { team: Team; }; /** * Paginated list of team members */ export type TeamMembersListResponse = { members: Array; total_count: number; page: number; page_size: number; }; /** * Request body for sending team invitations (1–50 email addresses per request) */ export type SendInvitationsRequest = { emails: Array; /** * Role granted to invitees when they accept */ role: 'member' | 'admin'; }; /** * Response after successfully accepting a team invitation */ export type AcceptInvitationResponse = { team_id: string; team_name: string; message: string; }; /** * RFC 9457 problem details returned when team deletion is blocked (HTTP 409). * Codes are UPPERCASE and all `metadata` values are strings: * - `TEAM_HAS_MEMBERS` — metadata: `member_count` (stringified integer) * */ export type TeamDeleteConflictError = { /** * URI reference that identifies the problem type */ type: string; /** * Short, human-readable summary of the problem type */ title: 'Team Has Members'; status: number; /** * Human-readable explanation specific to this occurrence */ detail: string; code: 'TEAM_HAS_MEMBERS'; request_id: string; timestamp: string; /** * URI reference that identifies the specific occurrence */ instance?: string; /** * Code-specific string-valued metadata (see schema description for per-code keys) */ metadata?: { [key: string]: string; }; }; export type InvitationDuplicateMembersError = { type?: string; title: string; status: number; detail?: string; code: string; /** * The submitted emails that already belong to team members */ duplicate_emails?: Array; }; export type TeamStatsResponse = { /** * Total number of projects belonging to this team */ total_projects: number; /** * Total number of prompts belonging to this team */ total_prompts: number; /** * Total number of artifacts belonging to this team */ total_artifacts: number; /** * Total number of blueprints belonging to this team */ total_blueprints: number; /** * Total number of memories belonging to this team */ total_memories: number; /** * Total number of feed items belonging to this team */ total_feed_items: number; }; export type TeamResourceCreationMetricsResponse = { status: string; message: string; data: TeamResourceCreationMetricsData; }; export type TeamFeedCreationMetricsResponse = { status: string; message: string; data: TeamFeedCreationMetricsData; }; export type TeamTopAccessedResourcesResponse = { status: string; message: string; data: TeamTopAccessedResourcesData; }; /** * List of the current user's pending team invitations (page/page_size are fixed at 1/20; all pending invitations are returned) */ export type PendingInvitationsListResponse = { invitations: Array; total_count: number; page: number; page_size: number; }; /** * An in-app notification delivered to a user */ export type Notification = { /** * Unique notification identifier */ id: string; /** * Team context the notification relates to (omitted when not team-scoped) */ team_id?: string; /** * Semantic notification type */ type: string; /** * Urgency/priority classification */ category: 'high' | 'low'; /** * Short notification headline */ title: string; /** * Optional longer plain-text description (omitted when empty) */ body?: string; /** * Optional deep-link URL for the notification action (omitted when empty) */ action_url?: string; /** * Optional structured metadata about the related entity (omitted when empty) */ entity_ref?: { [key: string]: unknown; }; /** * Timestamp when the notification was read (omitted while unread) */ read_at?: string; /** * Timestamp when the notification was dismissed (omitted when not dismissed) */ dismissed_at?: string; /** * Timestamp when the notification was created */ created_at: string; }; /** * Paginated list of notifications for the authenticated user */ export type NotificationListResponse = { /** * Notifications in this page, newest first */ notifications: Array; /** * Number of items in this page (≤ limit), NOT the global total */ count: number; /** * Page size used for this request */ limit: number; /** * Offset used for this request */ offset: number; }; /** * Unread notification count for the authenticated user */ export type UnreadCountResponse = { /** * Total number of unread notifications */ unread_count: number; }; /** * A resource category. System defaults are global and read-only (is_system true, no team_id); custom types belong to a team. Uniqueness is on (team_id, resource_type, slug). * */ export type Type = { /** * Unique type identifier */ id: string; /** * Owning team; omitted for global system defaults */ team_id?: string; /** * Resource the type applies to (e.g. "artifacts") */ resource_type: string; /** * URL-safe identifier, unique per (team, resource_type) */ slug: string; /** * Human-readable display name */ name: string; /** * True for built-in defaults that cannot be edited or deleted */ is_system: boolean; /** * Timestamp when the type was created */ created_at: string; }; /** * Request body for creating a team-owned custom type */ export type CreateTypeRequest = { /** * Resource the type applies to (currently only "artifacts") */ resource_type: string; /** * URL-safe identifier (lowercase letters, numbers, hyphens) */ slug: string; /** * Human-readable display name */ name: string; }; /** * System defaults plus the team's custom types for a resource */ export type TypeListResponse = { /** * Types visible to the team, system defaults first */ types: Array; /** * Number of types in the list */ total_count: number; }; /** * Request body for copying another team's custom types into this one. The destination is the `{team_id}` path parameter; only the source is carried here. * */ export type CopyTypesRequest = { /** * Team to copy the custom types from. The caller must belong to it, and it must differ from the destination team. * */ source_team_id: string; }; /** * A source type that was not copied because the destination already has a type with the same slug for that resource. A skip is a normal outcome, never an error. * */ export type SkippedType = { /** * Resource the skipped type applies to */ resource_type: string; /** * Slug that already exists in the destination team */ slug: string; }; /** * Outcome of copying a team's custom types. The copy is a merge: types whose slug is free in the destination are added, the rest are reported as skipped. System defaults are never part of the source set — every team already has them. * */ export type CopyTypesResponse = { /** * Types created in the destination team */ added: Array; /** * Source types left untouched because their slug is already taken */ skipped: Array; /** * Number of types created in the destination team */ added_count: number; /** * Number of source types skipped */ skipped_count: number; }; /** * A team-visible comment on a resource. */ export type Comment = { /** * Unique comment identifier */ id: string; /** * Owning team */ team_id: string; /** * Type of the commented resource (artifact, memory, prompt, or blueprint) */ resource_type: string; /** * Identifier of the commented resource */ resource_id: string; /** * Author of the comment */ user_id: string; /** * Comment body (markdown, 1–10,000 characters) */ content: string; /** * When the comment was created */ created_at: string; /** * When the comment was last edited (equals created_at if never edited) */ updated_at: string; }; /** * Request body for creating a comment on a resource. */ export type CreateCommentRequest = { /** * Type of the resource being commented on (artifact, memory, prompt, or blueprint) */ resource_type: string; /** * Identifier of the resource being commented on */ resource_id: string; /** * Comment body (markdown, 1–10,000 characters) */ content: string; }; /** * Request body for editing a comment's content. */ export type UpdateCommentRequest = { /** * New comment body (markdown, 1–10,000 characters) */ content: string; }; /** * A page of a resource's comments, newest first. */ export type CommentListResponse = { /** * Comments on the resource, newest first */ comments: Array; /** * Total number of comments on the resource */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; /** * A recent comment for the homepage activity card: the comment's latest state plus its resource's resolved title and link fields. No comment body snippet. project_id is present for every resource type; slug is present for artifact/blueprint/prompt and absent for memory. * */ export type RecentComment = { /** * Author of the comment */ user_id: string; /** * When the comment was created */ created_at: string; /** * When the comment was last edited (updated_at > created_at means edited) */ updated_at: string; /** * Type of the commented resource */ resource_type: string; /** * Identifier of the commented resource */ resource_id: string; /** * Resolved display title of the resource */ resource_title: string; /** * Project the resource belongs to (for building the detail link) */ project_id?: string; /** * Resource slug for the detail link (absent for memories) */ slug?: string; }; /** * The team's most recent comment activity, latest-activity first. */ export type RecentCommentListResponse = { /** * Recent comments across the team, most-recently-active first */ comments: Array; /** * Number of entries in the list */ total_count: number; }; /** * A directed, typed edge between two resources within a project. */ export type Relation = { /** * Unique relation identifier */ id: string; /** * Owning team */ team_id: string; /** * Project both endpoints belong to */ project_id: string; /** * Subject resource type (artifact, memory, prompt, or blueprint) */ from_type: string; /** * Subject resource identifier */ from_id: string; /** * Object resource type (artifact, memory, prompt, or blueprint) */ to_type: string; /** * Object resource identifier */ to_id: string; /** * The edge's intent */ relation_type: 'governed-by' | 'supersedes' | 'built-from' | 'explained-by'; /** * Whether a human or the AI proposed the edge */ origin: 'ai' | 'human'; /** * Tiered-trust lifecycle state */ status: 'suggested' | 'confirmed'; /** * User who created the edge (absent if that user was deleted) */ created_by?: string; /** * User who confirmed the edge (absent while suggested or if that user was deleted) */ confirmed_by?: string; /** * When the edge was created */ created_at: string; /** * When the edge was last updated (e.g. confirmed) */ updated_at: string; }; /** * Request body for creating a typed relation between two resources. */ export type CreateRelationRequest = { /** * Subject resource type (artifact, memory, prompt, or blueprint) */ from_type: 'artifact' | 'memory' | 'prompt' | 'blueprint'; /** * Subject resource identifier */ from_id: string; /** * Object resource type (artifact, memory, prompt, or blueprint) */ to_type: 'artifact' | 'memory' | 'prompt' | 'blueprint'; /** * Object resource identifier */ to_id: string; /** * The edge's intent. The object type is constrained per relation type: governed-by -> blueprint, built-from -> prompt, explained-by -> memory, supersedes -> same type as the subject. * */ relation_type: 'governed-by' | 'supersedes' | 'built-from' | 'explained-by'; /** * Whether a human or the AI proposed the edge */ origin: 'ai' | 'human'; }; /** * One endpoint of a relation as seen from the other endpoint, enriched with the related resource's resolved title and link fields. project_id is present for every type; slug is present for artifact/blueprint/prompt and absent for memory. * */ export type RelatedResource = { /** * The relation this entry came from */ relation_id: string; /** * The edge's intent */ relation_type: 'governed-by' | 'supersedes' | 'built-from' | 'explained-by'; /** * Whether the queried resource is the subject (outgoing) or object (incoming) of the edge */ direction: 'outgoing' | 'incoming'; /** * Whether a human or the AI proposed the edge */ origin: 'ai' | 'human'; /** * Tiered-trust lifecycle state */ status: 'suggested' | 'confirmed'; /** * Type of the related (other) resource */ resource_type: string; /** * Identifier of the related (other) resource */ resource_id: string; /** * Resolved display title of the related resource */ title: string; /** * Project the related resource belongs to */ project_id?: string; /** * Related resource slug for the detail link (absent for memories) */ slug?: string; /** * When the edge was created */ created_at: string; }; /** * An embedding-similarity neighbor of a resource, COMPUTED live at read time from vector similarity — never a stored edge, and kept strictly distinct from the typed `related` edges. Score is 1 - cosine_distance (higher is closer). * */ export type SimilarResource = { /** * Identifier of the similar resource */ id: string; /** * Type of the similar resource (artifact, memory, prompt, or blueprint) */ type: string; /** * Resolved display title of the similar resource */ title: string; /** * Similarity score, 1 - cosine_distance (higher is closer) */ score: number; }; /** * A page of the relations touching a resource (both directions), newest first. */ export type RelationListResponse = { /** * Relations touching the resource, newest first */ relations: Array; /** * Total number of relations touching the resource */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; export type MetadataKeysResponse = { /** * Distinct metadata keys present on the caller's rows of the requested resource type, in ascending order. */ keys: Array; /** * True when more distinct keys exist than the requested limit returned. */ truncated: boolean; }; export type MetadataValuesResponse = { /** * Distinct values stored under the requested key, in ascending order. Values held in an array are flattened, and non-string scalars are rendered in their text form. Keys whose value is a JSON object are skipped, since they have no meaningful value list. */ values: Array; /** * True when more distinct values exist than the requested limit returned. */ truncated: boolean; }; /** * One team's rule for when a resource becomes stale. */ export type FreshnessRule = { /** * Rule identifier. */ id: string; /** * Team the rule belongs to. */ team_id: string; /** * Scopes the rule to a single project. `null` means the rule applies to EVERY project in the team. * */ project_id: string | null; /** * Resource types the rule applies to. Never empty. */ resource_types: Array; /** * Access mediums that count as "accessed" for this rule. An EMPTY array means ANY medium counts — it does not mean "no medium". * */ mediums: Array; /** * Days without a qualifying access after which the resource is stale. Capped at 36500 (100 years), mirroring the search-settings half-life cap: past that the rule can never fire, and the bound keeps the value inside the int32 the column and the wire format use. * */ threshold_days: number; /** * Whether evaluation runs apply this rule. */ enabled: boolean; created_at: string; updated_at: string; }; /** * A resource type a freshness rule can cover. */ export type FreshnessRuleResourceType = 'artifact' | 'prompt' | 'blueprint' | 'memory'; /** * An access medium that counts as "accessed" for a freshness rule. Note this is narrower than the set of mediums recorded on the access path — `api` accesses are stored but are deliberately not selectable as rule criteria. * */ export type FreshnessRuleMedium = 'web' | 'cli' | 'mcp'; /** * The team's freshness rules, oldest first. */ export type FreshnessRuleListResponse = { /** * Freshness rules. Serializes as `[]` when the team has none, never `null`. */ rules: Array; }; /** * Create a freshness rule. */ export type CreateFreshnessRuleRequest = { /** * Scope to one project; omit or send `null` for every project in the team. */ project_id?: string | null; resource_types: Array; /** * Omit or send an empty array to match any medium. */ mediums?: Array; threshold_days: number; /** * Defaults to true when omitted. */ enabled?: boolean; }; /** * Replace a freshness rule in full. */ export type UpdateFreshnessRuleRequest = { /** * Scope to one project; `null` means every project in the team. */ project_id: string | null; resource_types: Array; /** * An empty array matches any medium. */ mediums: Array; threshold_days: number; enabled: boolean; }; /** * The tunable freshness-evaluation values, shared by the current settings and the defaults. */ export type FreshnessSettingsValues = { /** * How often the team's rules are evaluated. Storage enforces a one-hour floor, matching the scheduler's own floor; the 31536000 (365-day) ceiling keeps the value inside the int32 the column and the wire format use, and an interval longer than a year is indistinguishable from off. * */ interval_seconds: number; /** * Whether accessing or editing a stale resource clears its stale state. */ reversibility_enabled: boolean; }; /** * The freshness settings in effect for a team, with their provenance. A team that has never overridden them reports `source: instance` and the defaults. * */ export type TeamFreshnessSettings = { /** * `team` when the team stores its own settings, `instance` when it inherits the defaults. * */ source: 'instance' | 'team'; interval_seconds: number; reversibility_enabled: boolean; /** * The values a DELETE would restore. Present on every read so clients can preview a reset without a second call. * */ defaults: FreshnessSettingsValues; }; /** * Override the team's freshness settings. */ export type UpdateTeamFreshnessSettingsRequest = { /** * Rejected below 3600 (one hour) or above 31536000 (365 days). */ interval_seconds: number; reversibility_enabled: boolean; }; /** * The reporting window for a time-series metric. The options mirror the other analytics endpoints so one range selector drives every chart. * */ export type FreshnessMetricsRange = '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; /** * One calendar day (UTC) of freshness activity, zero-filled: every day in the window is present even when nothing happened. * */ export type FreshnessDailyStaleCount = { date: string; /** * Resources that became stale on this day. */ marked: number; /** * Resources that stopped being stale on this day, for any reason. */ cleared: number; /** * How many resources were stale at the END of this day — the level, not the flow. It is reconstructed by walking today's live count backwards through the recorded transitions, so it is exact only for the period the audit log covers; days before freshness evaluation first ran on this team read as the earliest known level rather than as zero. The most recent day reports the live count as of the request. The reconstruction is clamped at zero, so on a team whose rows were removed by a project or team deletion — which writes no audit entry — the series can flatten at 0 instead of satisfying stale_total[i] = stale_total[i-1] + marked[i] - cleared[i]. * */ stale_total: number; /** * The day's total ACTIVITY, marked + cleared — the sum of the two series, not the level. It is the field the shared time-series chart reads for its per-day total, which is why it is a flow rather than stale_total. * */ total: number; }; export type FreshnessOverTimeMetricsData = { range: FreshnessMetricsRange; /** * Resources marked stale across the whole window. */ total_marked: number; /** * Resources cleared across the whole window. */ total_cleared: number; /** * One entry per day in the window, oldest first. Serializes as `[]`, never `null`. */ counts: Array; }; export type FreshnessOverTimeMetricsResponse = { status: string; message: string; data: FreshnessOverTimeMetricsData; }; /** * How many of one resource type are stale right now. */ export type FreshnessTypeCount = { resource_type: FreshnessRuleResourceType; count: number; }; export type FreshnessByTypeMetricsData = { /** * Total stale resources in the team, across every type. */ total_stale: number; /** * One entry per resource type, always all four, in a stable order — a type with nothing stale reports 0 rather than being omitted, so the chart's bars never move. Serializes as `[]`, never `null`. * */ counts: Array; }; export type FreshnessByTypeMetricsResponse = { status: string; message: string; data: FreshnessByTypeMetricsData; }; /** * How many resources are stale right now in one project. `name` and `slug` are carried so the client can label and deep-link the bar without a second request. * */ export type FreshnessProjectCount = { project_id: string; name: string; slug: string; count: number; }; export type FreshnessByProjectMetricsData = { total_stale: number; /** * One entry per project in the team, including projects with nothing stale (0), ordered by count descending then name. Serializes as `[]`, never `null`. * */ counts: Array; }; export type FreshnessByProjectMetricsResponse = { status: string; message: string; data: FreshnessByProjectMetricsData; }; /** * How many resources one rule currently marks. Rules have no name, so the defining fields travel with the count for the client to label the bar. * */ export type FreshnessRuleImpact = { rule_id: string; /** * The project the rule is scoped to, or null for every project in the team. */ project_id: string | null; resource_types: Array; threshold_days: number; /** * A disabled rule reports 0 — it is listed so its absence from the chart is not mistaken for deletion. */ enabled: boolean; count: number; }; export type FreshnessByRuleMetricsData = { /** * Distinct stale resources in the team. It is NOT the sum of the per-rule counts: a resource matched by two rules is counted once here and once under each rule, because staleness is a union across rules. * */ total_stale: number; /** * One entry per rule the team has defined, including rules matching nothing, ordered by count descending then rule id. Serializes as `[]`, never `null`. * */ counts: Array; }; export type FreshnessByRuleMetricsResponse = { status: string; message: string; data: FreshnessByRuleMetricsData; }; /** * One recorded freshness transition. The log is append-only. */ export type FreshnessAuditEntry = { id: string; resource_type: FreshnessRuleResourceType; resource_id: string; /** * The rule that caused the change, when exactly one did. Null for a reversal (caused by a read or an edit) and for a mark attributable to several rules at once — the resource's own state carries the full set. * */ rule_id: string | null; /** * Whether the resource became stale or stopped being stale. */ action: 'marked' | 'cleared'; /** * What caused it — a scheduled evaluation, a read, or an edit. */ reason: 'rule_run' | 'accessed' | 'edited'; /** * The resource's current slug, resolved at read time so a client can deep-link the row. Null when the resource no longer exists, and always null for memories, which are deep-linked by id and have no slug column. Deliberately not stored on the log: slugs are mutable, so a stored copy would rot on the next rename and produce a confident link that 404s. * */ slug?: string | null; /** * The project the resource currently belongs to, resolved at read time. Null when the resource no longer exists. Required alongside the slug to deep-link artifacts and blueprints. * */ project_id?: string | null; created_at: string; }; /** * A page of the team's freshness audit log, newest first. */ export type FreshnessAuditListResponse = { /** * Serializes as `[]` when the page is empty, never `null`. */ entries: Array; /** * Total entries in the team's log, ignoring pagination. */ total_count: number; /** * Current page number (1-based) */ page: number; /** * Number of entries per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; /** * The resource's staleness state. Present only when the resource is stale; absent means fresh. * */ export type ResourceFreshnessState = { /** * Today the only state a resource can be in while it has freshness state at all. It is modelled as an enum rather than a boolean so a future state can be added without changing the field's type. * */ status: 'stale'; /** * When the resource was FIRST marked stale. It is preserved across re-evaluations that keep it stale, so it is the age a client can show. * */ since: string; /** * Every rule that currently marks this resource — staleness is a union across rules, so this answers "why is this stale". Serializes as `[]`, never `null`. * */ matched_rule_ids: Array; /** * What produced the current state. */ reason: 'rule_run' | 'accessed' | 'edited'; }; /** * The search ranking settings in effect for a team, with enough context for a client to render the whole settings surface from this one response: the effective values, where they came from, the instance defaults to preview a reset against, and the instance-owned candidate cap. * */ export type TeamSearchSettings = { /** * Where the effective values come from. `instance` means the team has no override and inherits the deployment defaults; `team` means the team has stored its own profile. * */ source: 'instance' | 'team'; /** * Effective value — the team's when source is `team`, otherwise the instance default. */ recency_ranking_enabled: boolean; /** * Effective value — the team's when source is `team`, otherwise the instance default. */ rank_weight_relevance: number; /** * Effective value — the team's when source is `team`, otherwise the instance default. */ rank_weight_created: number; /** * Effective value — the team's when source is `team`, otherwise the instance default. */ rank_weight_updated: number; /** * Effective value — the team's when source is `team`, otherwise the instance default. */ rank_half_life_days: number; instance_defaults: TeamSearchSettingsValues; /** * How many top-by-relevance rows are pulled and re-ranked in memory per query. Instance-owned and NOT team-configurable — one team must not be able to raise the whole deployment's per-query cost. Exposed so clients can explain why pagination is clamped to this many results when recency ranking is on. * Deliberately NOT marked `readOnly`: the update request uses a separate schema that has no such field, which is what actually makes the cap unsettable. Marking it readOnly additionally makes oapi-codegen emit it as an optional pointer, which would let a required field serialize as absent. * */ rank_candidate_cap: number; }; /** * A complete search ranking profile. The three weights are normalized by their sum at ranking time, so they need not pre-sum to 1. * */ export type TeamSearchSettingsValues = { /** * When false, results keep relevance-only ordering. When true they are re-ranked by a weighted blend of relevance and freshness. * */ recency_ranking_enabled: boolean; /** * Weight of semantic relevance. Expected to be the dominant weight. */ rank_weight_relevance: number; /** * Weight of how recently the resource was created. */ rank_weight_created: number; /** * Weight of how recently the resource was updated. */ rank_weight_updated: number; /** * Half-life in days for the exponential freshness decay applied to both created_at and updated_at. An item exactly one half-life old scores 0.5. * */ rank_half_life_days: number; }; /** * A complete replacement ranking profile for the team. There is no partial update: every field is required, and the whole profile is stored or replaced atomically. `rank_candidate_cap` is deliberately absent — it is instance-owned. * */ export type UpdateTeamSearchSettingsRequest = { recency_ranking_enabled: boolean; rank_weight_relevance: number; rank_weight_created: number; rank_weight_updated: number; rank_half_life_days: number; }; /** * Which settings surface was copied between teams. */ export type TeamSettingsAuditSurface = 'embedding_provider' | 'model_provider' | 'custom_types'; /** * One recorded settings copy into this team: which surface arrived, who brought it, and where it came from. * */ export type TeamSettingsAuditEntry = { /** * Identifier of the audit entry. */ id: string; surface: TeamSettingsAuditSurface; /** * Who performed the copy. `null` once that account is deleted — the entry outlives the actor on purpose, so that deletion cannot erase the record of what the account did. * */ actor_user_id: string | null; /** * The actor's display name (their email when the name is blank), resolved server-side so a client need not fan out per row. `null` when `actor_user_id` is null or no longer resolves to a user. * */ actor_name: string | null; /** * The team the configuration was copied FROM. */ source_team_id: string | null; /** * The source team's name, resolved server-side. `null` when that team has since been deleted — the id above is then the only remaining handle on it, and is deliberately still present rather than blanked. * */ source_team_name: string | null; /** * The resource that was copied. `null` for a `custom_types` copy, where one action copies a whole set and the individual ids live in `detail`. * */ source_resource_id: string | null; /** * The resource created in this team. `null` for a `custom_types` copy, for the same reason as `source_resource_id`. * */ created_resource_id: string | null; /** * Surface-specific facts snapshotted at write time — resource names, and for a provider copy whether it carried a credential and whether it became the team's active provider. Always an object, never null. * */ detail: { [key: string]: unknown; }; /** * When the copy was recorded. */ created_at: string; }; /** * A page of the team's settings audit log, newest first. */ export type TeamSettingsAuditListResponse = { /** * Serializes as `[]` when the page is empty, never `null`. */ entries: Array; /** * Total entries in the team's log, ignoring pagination. */ total_count: number; /** * Current page number (1-based) */ page: number; /** * Number of entries per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; /** * Instance-wide totals for the top-level entities (unscoped counts). */ export type AdminInstanceCounts = { /** * Total number of user accounts. */ users: number; /** * Total number of teams. */ teams: number; /** * Total number of prompts. */ prompts: number; /** * Total number of artifacts. */ artifacts: number; /** * Total number of memories. */ memories: number; }; /** * Instance statistics returned by GET /api/v1/admin/stats. */ export type AdminStatsResponse = { counts: AdminInstanceCounts; /** * The running backend application version (config server.service_version; "dev" when unset). */ version: string; }; /** * One user in the instance-wide admin user listing. */ export type AdminUserListItem = { id: string; email: string; name: string; /** * Identity provider name (e.g. "google", "oidc"); null for accounts without one. */ idp_provider?: string | null; /** * Account lifecycle. A suspended account is rejected at every * authentication entry point — existing sessions, API keys and MCP/OAuth * tokens stop working immediately, not at expiry. Instance-local: it does * not disable the account at the upstream identity provider. * */ status: 'active' | 'suspended'; created_at: string; /** * Number of teams the user belongs to. */ team_count: number; }; /** * A page of the instance-wide user listing, newest first. */ export type AdminUserListResponse = { /** * Users on this page, newest first. */ users: Array; /** * Total number of users across the instance. */ total_count: number; /** * Current page number. */ page: number; /** * Number of items per page. */ per_page: number; /** * Total number of pages. */ total_pages: number; }; /** * A team the user belongs to, with the user's role in that team. */ export type AdminTeamMembership = { team_id: string; team_name: string; /** * The user's role in the team (owner, admin, or member). */ role: string; }; /** * A single user with their team memberships (GET /api/v1/admin/users/{id}). */ export type AdminUserDetail = { id: string; email: string; name: string; /** * Identity provider name (e.g. "google", "oidc"); null for accounts without one. */ idp_provider?: string | null; /** * Account lifecycle. A suspended account is rejected at every * authentication entry point — existing sessions, API keys and MCP/OAuth * tokens stop working immediately, not at expiry. Instance-local: it does * not disable the account at the upstream identity provider. * */ status: 'active' | 'suspended'; created_at: string; /** * Teams the user belongs to. */ memberships: Array; }; /** * A user shown as the responsible party for a resource: the owner of a team, or * the creator of a project (#453). The shape is id/email/name in both cases; * which relationship it represents is stated on the referencing property. * */ export type AdminTeamOwner = { id: string; email: string; name: string; }; /** * One team in the instance-wide admin team listing. */ export type AdminTeamListItem = { id: string; name: string; /** * URL-safe team identifier. */ slug: string; /** * True for a user's default personal workspace, false for a shared team workspace. */ is_personal: boolean; owner: AdminTeamOwner; /** * Number of members in the team. */ member_count: number; created_at: string; }; /** * A page of the instance-wide team listing, newest first. */ export type AdminTeamListResponse = { /** * Teams on this page, newest first. */ teams: Array; /** * Total number of teams across the instance. */ total_count: number; page: number; per_page: number; total_pages: number; }; /** * One member of a team, with the member's role and join time. */ export type AdminTeamMember = { user_id: string; email: string; name: string; /** * The member's role in the team (owner, admin, or member). */ role: string; joined_at: string; }; /** * A single team with its owner and member list (GET /api/v1/admin/teams/{id}). */ export type AdminTeamDetail = { id: string; name: string; /** * URL-safe team identifier. */ slug: string; /** * True for a user's default personal workspace, false for a shared team workspace. */ is_personal: boolean; owner: AdminTeamOwner; created_at: string; /** * The team's members. */ members: Array; }; /** * Instance-wide totals for every top-level entity. A superset of * AdminInstanceCounts, which stays as-is for the legacy stats endpoint. * */ export type AdminExtendedCounts = { users: number; teams: number; projects: number; prompts: number; artifacts: number; memories: number; blueprints: number; agents: number; feeds: number; api_keys: number; }; /** * One value of a grouped column plus how many rows carry it. */ export type AdminBreakdownBucket = { /** * The column value. NULL values are reported as an empty string. */ value: string; count: number; }; /** * A GROUP BY over one status/type column of one entity table. */ export type AdminEntityBreakdown = { /** * The entity table the breakdown covers. */ entity: string; /** * The grouped column. */ field: string; /** * One entry per distinct value, most frequent first. */ buckets: Array; }; /** * Approximate row count for one table. */ export type AdminTableStat = { table: string; /** * ESTIMATE from pg_stat_user_tables.n_live_tup, not an exact COUNT(*) — * an exact per-table count does not scale and this figure is only meant * for relative sizing. Freshness depends on autovacuum/ANALYZE. * */ estimated_rows: number; }; /** * Instance storage health. */ export type AdminSystemHealth = { /** * pg_database_size(current_database()). */ database_size_bytes: number; /** * Per-table estimated row counts, largest first. */ tables: Array; }; /** * Totals, breakdowns and system health (GET /api/v1/admin/dashboard/overview). */ export type AdminDashboardOverview = { counts: AdminExtendedCounts; /** * One entry per entity/column pair that has a status or type column. */ breakdowns: Array; system_health: AdminSystemHealth; /** * The running backend application version ("dev" when unset). */ version: string; }; /** * New rows created per entity within one time bucket. */ export type AdminGrowthPoint = { /** * Start of the bucket, in UTC. */ bucket: string; users: number; teams: number; projects: number; prompts: number; artifacts: number; memories: number; }; /** * A single count within one time bucket. */ export type AdminCountPoint = { /** * Start of the bucket, in UTC. */ bucket: string; count: number; }; /** * A count for one access source within one time bucket. */ export type AdminSourcePoint = { /** * Start of the bucket, in UTC. */ bucket: string; /** * Access source (e.g. "web", "cli", "mcp"). */ source: string; count: number; }; /** * Earliest instant for which event data still exists. Both source tables are * TTL-pruned (config retention.activity_days / retention.access_event_days), * so a chart asking for a range older than these values will legitimately show * zeros rather than missing data. * */ export type AdminDataWindow = { /** * now() - retention.activity_days. */ sign_ins_earliest_retained_at: string; /** * now() - retention.access_event_days. */ access_by_source_earliest_retained_at: string; }; /** * Bucketed metrics over a time range (GET /api/v1/admin/dashboard/timeseries). * Every bucket in the requested range is present in every series with an * explicit 0 — the series are gap-filled, never sparse. * */ export type AdminTimeseriesResponse = { /** * Inclusive start of the range actually used. This is snapped DOWN to the * start of its bucket, so it may precede the requested `from` (asking for * 2026-07-15 at month granularity reports and queries 2026-07-01). Buckets * are therefore always whole, never partial at the head. * */ from: string; /** * Exclusive end of the range actually used (after defaulting). This is NOT * snapped, so the final bucket may cover only part of its period. * */ to: string; /** * Bucket size actually used. */ granularity: 'day' | 'week' | 'month'; /** * New entities per bucket, ascending by bucket. */ growth: Array; /** * Successful sign-ins per bucket (activities.auth_login), ascending. */ sign_ins: Array; /** * Resource accesses per bucket per source, ascending by bucket then source. * Only sources actually observed in the range appear; a source with no * events in a bucket is gap-filled to 0 for the sources that do appear. * */ access_by_source: Array; data_window: AdminDataWindow; }; /** * Fields an instance admin may change on a user. Deliberately minimal: email * and the identity-provider fields (idp_provider, idp_subject) are owned by the * upstream IdP and are not editable here — sending them is a 400 rather than a * silent no-op. * */ export type AdminUserUpdateRequest = { /** * The user's display name. */ name: string; }; /** * One reason a user cannot be deleted: a shared team they own that still has * other members. Ownership must be transferred before the account can be * removed. * */ export type AdminDeleteBlocker = { team_id: string; team_name: string; /** * How many members the team has, including the owner. */ member_count: number; }; /** * Returned with 409 when a hard delete is refused. NOTHING was deleted: the * user and every listed team still exist. * */ export type AdminUserDeleteBlockedResponse = { /** * Human-readable summary of why the delete was refused. */ message: string; /** * Every shared team blocking the delete. */ blockers: Array; }; /** * A user to create directly, without waiting for them to complete an * identity-provider sign-in. No password is set: VibeXP has no password * provider, and the account's owner still signs in through the configured IdP. * */ export type AdminUserCreateRequest = { /** * Must be unique across the instance; a duplicate is a 409. */ email: string; name: string; /** * Optional label recording which identity provider this account is expected * to sign in with (e.g. "google", "oidc"). Informational only — it does not * pre-link an IdP identity, which is established on first sign-in. * */ idp_provider?: string; }; /** * The team a project belongs to. */ export type AdminProjectTeam = { id: string; name: string; slug: string; }; /** * One project in the instance-wide admin project listing. */ export type AdminProjectListItem = { id: string; name: string; slug: string; team: AdminProjectTeam; /** * The project's creator (projects.user_id). This is NOT necessarily the * owning team's owner — a project carries both a team and a creating user, * and the two can differ. * */ owner: AdminTeamOwner; created_at: string; updated_at: string; }; /** * A page of the instance-wide project listing. */ export type AdminProjectListResponse = { /** * Projects on this page. */ projects: Array; /** * Total number of projects matching the filters. */ total_count: number; page: number; per_page: number; total_pages: number; }; /** * How many of each PROJECT-SCOPED resource type the project contains. * * Only these four types belong to a project. Agents and feeds are deliberately * absent: neither table has a project_id column (both are team-scoped), so * reporting zero for them would read as "this project has no agents" rather * than "agents do not belong to projects". * */ export type AdminProjectResourceCounts = { prompts: number; artifacts: number; memories: number; blueprints: number; }; /** * A single project with its team, owner and resource counts (GET /api/v1/admin/projects/{id}). */ export type AdminProjectDetail = { id: string; name: string; slug: string; /** * Empty string when unset (the column defaults to ''). */ description: string; /** * Empty string when unset. */ git_url: string; /** * Empty string when unset. */ homepage: string; team: AdminProjectTeam; /** * The project's creator (projects.user_id); see AdminProjectListItem.owner. */ owner: AdminTeamOwner; resource_counts: AdminProjectResourceCounts; created_at: string; updated_at: string; }; export type ProjectResponse = Project & { /** * Whether the project's git URL matches a repository accessible via the team's GitHub App installation */ github_connected: boolean; }; export type ResourceSelection = { /** * Migrate every resource of this type in the source project */ all?: boolean; /** * Explicit list of resource IDs to migrate (used when all is false) */ ids?: Array; }; export type ResourceSelections = { prompts?: ResourceSelection; artifacts?: ResourceSelection; blueprints?: ResourceSelection; feed_items?: ResourceSelection; }; export type MigrationRequest = { /** * ID of the destination project (must belong to the same team) */ destination_project_id: string; resources?: ResourceSelections; /** * How slug collisions in the destination project are handled */ conflict_policy?: 'skip' | 'rename' | 'overwrite'; }; export type ResourceInventoryItem = { /** * Resource identifier */ id: string; /** * Human-readable resource name */ name: string; }; export type ResourceInventory = { /** * Number of resources of this type in the source project */ count: number; /** * Resources of this type (omitted when empty) */ items?: Array; }; export type MigrationInventory = { prompts?: ResourceInventory; artifacts?: ResourceInventory; blueprints?: ResourceInventory; feed_items?: ResourceInventory; }; export type ResourceOutcome = { /** * Resource identifier */ id: string; /** * Why the resource was skipped or failed */ reason: string; }; export type ResourceMigrationCounts = { prompts?: number; artifacts?: number; blueprints?: number; feed_items?: number; }; export type ResourceMigrationOutcomes = { prompts?: Array; artifacts?: Array; blueprints?: Array; feed_items?: Array; }; export type MigrationResult = { migrated: ResourceMigrationCounts; skipped: ResourceMigrationOutcomes; failed: ResourceMigrationOutcomes; /** * Name of the source project */ source_project_name: string; /** * Name of the destination project */ destination_project_name: string; }; export type ActivityEnvelope = { status: string; message: string; data: Activity; }; export type ActivityListEnvelope = { status: string; message: string; data: ActivityListResponse; }; export type ActivityStatsEnvelope = { status: string; message: string; data: ActivityStatsResponse; }; export type ActivityTypesEnvelope = { status: string; message: string; data: ActivityTypesResponse; }; export type ActivityEntityTypesEnvelope = { status: string; message: string; data: Array; }; export type PreferencesResponse = { preferences: Preferences; /** * When the preferences were last persisted. Zero value (0001-01-01T00:00:00Z) when the user has never saved preferences and defaults are being returned. */ updated_at: string; }; export type UpdatePreferencesRequest = { email_notification?: EmailNotificationPreferences; notifications?: NotificationPreferences; }; export type FeedItemReply = { /** * Unique identifier for the reply */ id: string; /** * UUID of the team this reply belongs to */ team_id: string; /** * UUID of the feed item this reply belongs to */ feed_item_id: string; /** * Content of the reply */ content: string; /** * ID of the user who posted this reply */ posted_by_user_id: string; /** * Name of the AI assistant that posted this reply, null for human replies */ ai_assistant_name?: string | null; /** * Server-set timestamp when the reply was posted */ posted_at: string; }; export type CreateFeedItemReplyRequest = { /** * Content of the reply (leading/trailing whitespace is trimmed) */ content: string; /** * Optional name of the AI assistant posting this reply */ ai_assistant_name?: string; }; export type FeedItemReplyListResponse = { /** * List of feed item replies */ replies: Array; /** * Total number of replies for the feed item */ total_count: number; /** * Current page number */ page: number; /** * Number of items per page */ per_page: number; /** * Total number of pages */ total_pages: number; }; /** * Field-level validation error details */ export type ValidationError = { /** * Name of the field that failed validation */ field: string; /** * Human-readable error message */ message: string; /** * Validation error code */ code: string; /** * The constraint that was violated */ constraint?: string; }; /** * Resolved attribution for a version's author. Null when the version has no author (created_by is null) or the user can no longer be resolved. */ export type VersionAuthor = { /** * User ID of the author */ id: string; /** * Author's display name */ display_name: string; /** * Author's avatar URL, if any */ avatar_url: string | null; /** * Up to two uppercase initials derived from the display name */ initials: string; } | null; /** * Per-resource-type creation counts for a single calendar day (UTC), zero-filled. */ export type ProjectResourceCreationDailyCount = { date: string; prompts: number; artifacts: number; blueprints: number; memories: number; total: number; }; export type ProjectResourceCreationMetricsData = { /** * Sum of every creation count across the whole window. */ total_created: number; range: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; counts: Array; }; export type CredentialRequest = { /** * Credential type. Must match a supported security scheme the backend can apply: `apiKey` (header/query/cookie) or `http` (bearer/basic). `oauth2`, `openIdConnect` and `mutualTLS` are rejected at save time. */ type: 'apiKey' | 'http'; /** * The plain text credential value (will be encrypted on server) */ value: string; }; export type ConversationSummary = { conversation_id: string; agent_id: string; message_count: number; first_message: string; last_message: string; started_at: string; last_activity_at: string; last_status: string; }; export type AgentExecutionEvent = { id: string; execution_id: string; /** * Event type (task, status-update, artifact-update) */ event_type: string; event_data: { [key: string]: unknown; }; sequence_number: number; received_at: string; }; /** * Per-resource-type creation counts for a single calendar day (UTC), zero-filled. */ export type TeamResourceCreationDailyCount = { date: string; prompts: number; artifacts: number; blueprints: number; memories: number; projects: number; total: number; }; export type TeamResourceCreationMetricsData = { /** * Sum of every creation count across the whole window. */ total_created: number; range: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; counts: Array; }; /** * Per-feed-entity creation counts for a single calendar day (UTC), zero-filled. */ export type TeamFeedCreationDailyCount = { date: string; /** * Feeds (channels) created on this day. */ feeds: number; /** * Feed items (AI updates posted) created on this day. */ feed_items: number; /** * feeds + feed_items for this day. */ total: number; }; export type TeamFeedCreationMetricsData = { /** * Sum of every feed/feed_item creation across the whole window. */ total_created: number; range: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; counts: Array; }; /** * One row of the team's most-accessed resources ranking. */ export type TopAccessedResourceItem = { /** * The accessed resource's type (e.g. prompt, artifact, blueprint, memory, project). */ resource_type: string; resource_id: string; /** * Resolved display name of the resource (prompt/project name, artifact/blueprint title, or truncated memory text). Empty when the resource no longer exists. */ name: string; /** * Number of access events for the resource within the window. */ access_count: number; }; export type TeamTopAccessedResourcesData = { range: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; items: Array; }; export type EmailNotificationPreferences = { /** * Receive platform announcement emails */ platform_announcement: boolean; /** * Receive account security emails */ account_security: boolean; /** * Receive new feature emails */ new_feature: boolean; /** * Receive marketing and promotional emails */ marketing_promotional: boolean; }; export type NotificationChannelPreferences = { /** * Enable in-app notifications globally */ in_app: boolean; /** * Enable email notifications globally */ email: boolean; }; export type NotificationTypePreference = { /** * Deliver this notification type in-app */ in_app: boolean; /** * Email delivery mode for this notification type */ email: 'instant' | 'digest' | 'none'; }; export type NotificationPreferences = { channels: NotificationChannelPreferences; /** * Per-type delivery preferences keyed by notification type (e.g. "feed.item.created", "feed.reply.created") */ types: { [key: string]: NotificationTypePreference; }; }; export type Preferences = { email_notification: EmailNotificationPreferences; notifications: NotificationPreferences; }; export type PingData = { body?: never; path?: never; query?: never; url: '/ping'; }; export type PingResponses = { /** * Service is running */ 200: string; }; export type PingResponse = PingResponses[keyof PingResponses]; export type HealthData = { body?: never; path?: never; query?: never; url: '/health'; }; export type HealthResponses = { /** * Service health status */ 200: HealthResponse; }; export type HealthResponse2 = HealthResponses[keyof HealthResponses]; export type LoginData = { body?: never; path?: never; query?: { /** * Canonical name of the identity provider to use (e.g. `google`, * `github`, `oidc`). Optional when a single provider is enabled; * required when more than one is enabled. * */ provider?: string; }; url: '/api/v1/auth/login'; }; export type LoginErrors = { /** * The `provider` value is unknown/disabled, or it was omitted while * multiple providers are enabled. * */ 400: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; /** * No identity provider is configured (web login unavailable) */ 503: ErrorResponse; }; export type LoginError = LoginErrors[keyof LoginErrors]; export type LoginResponses = { /** * Authorization URL generated successfully */ 200: LoginResponse; }; export type LoginResponse2 = LoginResponses[keyof LoginResponses]; export type ListAuthProvidersData = { body?: never; path?: never; query?: never; url: '/api/v1/auth/providers'; }; export type ListAuthProvidersErrors = { /** * Internal server error */ 500: ErrorResponse; }; export type ListAuthProvidersError = ListAuthProvidersErrors[keyof ListAuthProvidersErrors]; export type ListAuthProvidersResponses = { /** * Enabled providers listed successfully */ 200: ProvidersResponse; }; export type ListAuthProvidersResponse = ListAuthProvidersResponses[keyof ListAuthProvidersResponses]; export type AuthCallbackData = { body?: never; path?: never; query: { /** * Authorization code returned by the identity provider after user authentication */ code: string; /** * CSRF state value that must match the signed `vx_state` cookie */ state?: string; }; url: '/api/v1/auth/callback'; }; export type AuthCallbackErrors = { /** * Authorization code is missing */ 400: ErrorResponse; /** * Invalid or expired CSRF state cookie */ 401: ErrorResponse; /** * Identity provider authentication failed or session could not be created */ 500: ErrorResponse; }; export type AuthCallbackError = AuthCallbackErrors[keyof AuthCallbackErrors]; export type LogoutData = { body?: never; path?: never; query?: never; url: '/api/v1/auth/logout'; }; export type LogoutErrors = { /** * Internal server error */ 500: ErrorResponse; }; export type LogoutError = LogoutErrors[keyof LogoutErrors]; export type LogoutResponses = { /** * Logged out successfully */ 200: LogoutResponse; }; export type LogoutResponse2 = LogoutResponses[keyof LogoutResponses]; export type DevLoginData = { body: DevLoginRequest; path?: never; query?: never; url: '/api/v1/auth/dev/login'; }; export type DevLoginErrors = { /** * Invalid request body or missing required fields */ 400: ErrorResponse; /** * Sign-in denied by the access allowlist. The response `code` is the * stable string `access_restricted`. * */ 403: ErrorResponse; /** * Endpoint not available outside development environment */ 404: ErrorResponse; /** * Authentication failed or session could not be created */ 500: ErrorResponse; }; export type DevLoginError = DevLoginErrors[keyof DevLoginErrors]; export type DevLoginResponses = { /** * Dev authentication successful — session cookie set, user object returned */ 200: User; }; export type DevLoginResponse = DevLoginResponses[keyof DevLoginResponses]; export type GetMeData = { body?: never; path?: never; query?: never; url: '/api/v1/auth/me'; }; export type GetMeErrors = { /** * Unauthorized - invalid or missing session cookie */ 401: ErrorResponse; /** * User not found */ 404: ErrorResponse; }; export type GetMeError = GetMeErrors[keyof GetMeErrors]; export type GetMeResponses = { /** * User information retrieved successfully */ 200: CurrentUser; }; export type GetMeResponse = GetMeResponses[keyof GetMeResponses]; export type ListApiKeysData = { body?: never; path?: never; query?: { /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/api-keys'; }; export type ListApiKeysErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type ListApiKeysError = ListApiKeysErrors[keyof ListApiKeysErrors]; export type ListApiKeysResponses = { /** * API keys retrieved successfully */ 200: ApiKeyListResponse; }; export type ListApiKeysResponse = ListApiKeysResponses[keyof ListApiKeysResponses]; export type CreateApiKeyData = { body: CreateApiKeyRequest; path?: never; query?: never; url: '/api/v1/api-keys'; }; export type CreateApiKeyErrors = { /** * Invalid request data */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; }; export type CreateApiKeyError = CreateApiKeyErrors[keyof CreateApiKeyErrors]; export type CreateApiKeyResponses = { /** * API key created successfully */ 201: CreateApiKeyResponse; }; export type CreateApiKeyResponse2 = CreateApiKeyResponses[keyof CreateApiKeyResponses]; export type DeleteApiKeyData = { body?: never; path: { /** * API key ID */ id: string; }; query?: never; url: '/api/v1/api-keys/{id}'; }; export type DeleteApiKeyErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * API key not found */ 404: ErrorResponse; }; export type DeleteApiKeyError = DeleteApiKeyErrors[keyof DeleteApiKeyErrors]; export type DeleteApiKeyResponses = { /** * API key deleted successfully */ 200: SuccessResponse; }; export type DeleteApiKeyResponse = DeleteApiKeyResponses[keyof DeleteApiKeyResponses]; export type ListApiKeysSettingsData = { body?: never; path?: never; query?: { /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/settings/api-keys'; }; export type ListApiKeysSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type ListApiKeysSettingsError = ListApiKeysSettingsErrors[keyof ListApiKeysSettingsErrors]; export type ListApiKeysSettingsResponses = { /** * API keys retrieved successfully */ 200: ApiKeyListResponse; }; export type ListApiKeysSettingsResponse = ListApiKeysSettingsResponses[keyof ListApiKeysSettingsResponses]; export type CreateApiKeySettingsData = { body: CreateApiKeyRequest; path?: never; query?: never; url: '/api/v1/settings/api-keys'; }; export type CreateApiKeySettingsErrors = { /** * Invalid request data */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; }; export type CreateApiKeySettingsError = CreateApiKeySettingsErrors[keyof CreateApiKeySettingsErrors]; export type CreateApiKeySettingsResponses = { /** * API key created successfully */ 201: CreateApiKeyResponse; }; export type CreateApiKeySettingsResponse = CreateApiKeySettingsResponses[keyof CreateApiKeySettingsResponses]; export type DeleteApiKeySettingsData = { body?: never; path: { /** * API key ID */ id: string; }; query?: never; url: '/api/v1/settings/api-keys/{id}'; }; export type DeleteApiKeySettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * API key not found */ 404: ErrorResponse; }; export type DeleteApiKeySettingsError = DeleteApiKeySettingsErrors[keyof DeleteApiKeySettingsErrors]; export type DeleteApiKeySettingsResponses = { /** * API key deleted successfully */ 200: SuccessResponse; }; export type DeleteApiKeySettingsResponse = DeleteApiKeySettingsResponses[keyof DeleteApiKeySettingsResponses]; export type SubmitSupportRequestData = { body: SupportRequest; path?: never; query?: never; url: '/api/v1/support/message'; }; export type SubmitSupportRequestErrors = { /** * Invalid request data or validation error */ 400: SupportResponse; /** * Unauthorized - JWT token required */ 401: ErrorResponse; /** * Internal server error - failed to send support request */ 500: SupportResponse; }; export type SubmitSupportRequestError = SubmitSupportRequestErrors[keyof SubmitSupportRequestErrors]; export type SubmitSupportRequestResponses = { /** * Support request submitted successfully */ 200: SupportResponse; }; export type SubmitSupportRequestResponse = SubmitSupportRequestResponses[keyof SubmitSupportRequestResponses]; export type ListArtifactsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Filter to resources currently flagged stale by the team's freshness rules (epic #726). Omit for no freshness filtering. Returns 400 for any other value — a silently ignored filter would return the full list, which looks like a legitimate answer. */ freshness?: 'stale'; /** * Filter by project ID */ project_id?: string; /** * Filter by status */ status?: 'active' | 'draft' | 'archived'; /** * Filter by type. An open string matched against the team's registered types (the system defaults work_reports, static_contexts and general, plus any custom types the team has added), not a fixed enum. */ type?: string; /** * Search in title, description, and content */ search?: string; /** * Filter by metadata as a JSON object of key to array of string values. Keys are combined with AND, values within a key with OR, and an empty array means "the key exists". Values match metadata stored as a scalar or as an array, and numeric/boolean values are matched by their string form. At most 10 keys, 25 values per key, key length 255, value length 512. Example: {"env":["prod","staging"],"team":["core"]} */ metadata?: string; /** * Sort field */ sort_by?: 'created_at' | 'updated_at' | 'title'; /** * Sort order */ sort_order?: 'asc' | 'desc'; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/artifacts'; }; export type ListArtifactsErrors = { /** * Invalid query parameter (for example a malformed `metadata` filter) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type ListArtifactsError = ListArtifactsErrors[keyof ListArtifactsErrors]; export type ListArtifactsResponses = { /** * Artifacts retrieved successfully */ 200: ArtifactListResponse; }; export type ListArtifactsResponse = ListArtifactsResponses[keyof ListArtifactsResponses]; export type CreateArtifactData = { body: CreateArtifactRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/artifacts'; }; export type CreateArtifactErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Artifact with same slug already exists in project */ 409: ErrorResponse; }; export type CreateArtifactError = CreateArtifactErrors[keyof CreateArtifactErrors]; export type CreateArtifactResponses = { /** * Artifact created successfully */ 201: Artifact; }; export type CreateArtifactResponse = CreateArtifactResponses[keyof CreateArtifactResponses]; export type GetArtifactStatsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/stats'; }; export type GetArtifactStatsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type GetArtifactStatsError = GetArtifactStatsErrors[keyof GetArtifactStatsErrors]; export type GetArtifactStatsResponses = { /** * Artifact statistics retrieved successfully */ 200: ArtifactStatsResponse; }; export type GetArtifactStatsResponse = GetArtifactStatsResponses[keyof GetArtifactStatsResponses]; export type ListArtifactsByProjectData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; }; query?: { /** * Filter to resources currently flagged stale by the team's freshness rules (epic #726). Omit for no freshness filtering. Returns 400 for any other value — a silently ignored filter would return the full list, which looks like a legitimate answer. */ freshness?: 'stale'; /** * Filter by status */ status?: 'active' | 'draft' | 'archived'; /** * Filter by type. An open string matched against the team's registered types (the system defaults work_reports, static_contexts and general, plus any custom types the team has added), not a fixed enum. */ type?: string; /** * Search in title, description, and content */ search?: string; /** * Filter by metadata as a JSON object of key to array of string values. Keys are combined with AND, values within a key with OR, and an empty array means "the key exists". Values match metadata stored as a scalar or as an array, and numeric/boolean values are matched by their string form. At most 10 keys, 25 values per key, key length 255, value length 512. Example: {"env":["prod","staging"],"team":["core"]} */ metadata?: string; /** * Sort field */ sort_by?: 'created_at' | 'updated_at' | 'title'; /** * Sort order */ sort_order?: 'asc' | 'desc'; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/artifacts/{project_id}'; }; export type ListArtifactsByProjectErrors = { /** * Invalid query parameter (for example a malformed `metadata` filter) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type ListArtifactsByProjectError = ListArtifactsByProjectErrors[keyof ListArtifactsByProjectErrors]; export type ListArtifactsByProjectResponses = { /** * Artifacts retrieved successfully */ 200: ArtifactListResponse; }; export type ListArtifactsByProjectResponse = ListArtifactsByProjectResponses[keyof ListArtifactsByProjectResponses]; export type DeleteArtifactData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}'; }; export type DeleteArtifactErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact not found */ 404: ErrorResponse; }; export type DeleteArtifactError = DeleteArtifactErrors[keyof DeleteArtifactErrors]; export type DeleteArtifactResponses = { /** * Artifact deleted successfully */ 204: void; }; export type DeleteArtifactResponse = DeleteArtifactResponses[keyof DeleteArtifactResponses]; export type GetArtifactData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}'; }; export type GetArtifactErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact not found */ 404: ErrorResponse; }; export type GetArtifactError = GetArtifactErrors[keyof GetArtifactErrors]; export type GetArtifactResponses = { /** * Artifact retrieved successfully */ 200: Artifact; }; export type GetArtifactResponse = GetArtifactResponses[keyof GetArtifactResponses]; export type UpdateArtifactData = { body: UpdateArtifactRequest; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}'; }; export type UpdateArtifactErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact not found */ 404: ErrorResponse; /** * Artifact with same slug already exists in project */ 409: ErrorResponse; }; export type UpdateArtifactError = UpdateArtifactErrors[keyof UpdateArtifactErrors]; export type UpdateArtifactResponses = { /** * Artifact updated successfully */ 200: Artifact; }; export type UpdateArtifactResponse = UpdateArtifactResponses[keyof UpdateArtifactResponses]; export type ListAttachmentsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query: { /** * Type of the owning resource (e.g. "artifact") */ owner_type: string; /** * UUID of the owning resource */ owner_id: string; }; url: '/api/v1/{team_id}/attachments'; }; export type ListAttachmentsErrors = { /** * Missing or invalid owner_type / owner_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Unsupported owner_type, or the owning resource was not found / is not accessible */ 404: ErrorResponse; }; export type ListAttachmentsError = ListAttachmentsErrors[keyof ListAttachmentsErrors]; export type ListAttachmentsResponses = { /** * Attachments retrieved successfully */ 200: AttachmentListResponse; }; export type ListAttachmentsResponse = ListAttachmentsResponses[keyof ListAttachmentsResponses]; export type UploadAttachmentData = { body: { /** * Type of the owning resource (e.g. "artifact") */ owner_type: string; /** * UUID of the owning resource */ owner_id: string; /** * The file to attach */ file: Blob | File; /** * Optional path relative to the owner's directory (e.g. "scripts/helper.py"). Must be relative — no leading "/", no "..", no backslashes. Unique per owner. file_name stays the basename. */ relative_path?: string; }; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/attachments'; }; export type UploadAttachmentErrors = { /** * Missing fields/file, invalid owner_id, file too large, cumulative limit exceeded, or disallowed type */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Unsupported owner_type, or the owning resource was not found / is not accessible */ 404: ErrorResponse; /** * Attachment storage is not available */ 503: ErrorResponse; }; export type UploadAttachmentError = UploadAttachmentErrors[keyof UploadAttachmentErrors]; export type UploadAttachmentResponses = { /** * Attachment uploaded successfully */ 201: Attachment; }; export type UploadAttachmentResponse = UploadAttachmentResponses[keyof UploadAttachmentResponses]; export type DeleteAttachmentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Attachment identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/attachments/{id}'; }; export type DeleteAttachmentErrors = { /** * Invalid attachment id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Attachment not found, or its owner is not accessible */ 404: ErrorResponse; }; export type DeleteAttachmentError = DeleteAttachmentErrors[keyof DeleteAttachmentErrors]; export type DeleteAttachmentResponses = { /** * Attachment deleted successfully */ 204: void; }; export type DeleteAttachmentResponse = DeleteAttachmentResponses[keyof DeleteAttachmentResponses]; export type DownloadAttachmentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Attachment identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/attachments/{id}'; }; export type DownloadAttachmentErrors = { /** * Invalid attachment id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Attachment not found, or its owner is not accessible */ 404: ErrorResponse; /** * Attachment storage is not available */ 503: ErrorResponse; }; export type DownloadAttachmentError = DownloadAttachmentErrors[keyof DownloadAttachmentErrors]; export type DownloadAttachmentResponses = { /** * Attachment file stream */ 200: Blob | File; }; export type DownloadAttachmentResponse = DownloadAttachmentResponses[keyof DownloadAttachmentResponses]; export type ListArtifactAttachmentsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/attachments'; }; export type ListArtifactAttachmentsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact not found */ 404: ErrorResponse; }; export type ListArtifactAttachmentsError = ListArtifactAttachmentsErrors[keyof ListArtifactAttachmentsErrors]; export type ListArtifactAttachmentsResponses = { /** * Attachments retrieved successfully */ 200: AttachmentListResponse; }; export type ListArtifactAttachmentsResponse = ListArtifactAttachmentsResponses[keyof ListArtifactAttachmentsResponses]; export type UploadArtifactAttachmentData = { body: { /** * The file to attach */ file: Blob | File; /** * Optional path relative to the owner's directory (e.g. "scripts/helper.py"). Must be relative — no leading "/", no "..", no backslashes. Unique per owner. file_name stays the basename. */ relative_path?: string; }; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/attachments'; }; export type UploadArtifactAttachmentErrors = { /** * Missing file, file too large, cumulative limit exceeded, or disallowed type */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact not found */ 404: ErrorResponse; /** * Attachment storage is not available */ 503: ErrorResponse; }; export type UploadArtifactAttachmentError = UploadArtifactAttachmentErrors[keyof UploadArtifactAttachmentErrors]; export type UploadArtifactAttachmentResponses = { /** * Attachment uploaded successfully */ 201: Attachment; }; export type UploadArtifactAttachmentResponse = UploadArtifactAttachmentResponses[keyof UploadArtifactAttachmentResponses]; export type DeleteArtifactAttachmentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; /** * Attachment identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/attachments/{id}'; }; export type DeleteArtifactAttachmentErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact or attachment not found */ 404: ErrorResponse; }; export type DeleteArtifactAttachmentError = DeleteArtifactAttachmentErrors[keyof DeleteArtifactAttachmentErrors]; export type DeleteArtifactAttachmentResponses = { /** * Attachment deleted successfully */ 204: void; }; export type DeleteArtifactAttachmentResponse = DeleteArtifactAttachmentResponses[keyof DeleteArtifactAttachmentResponses]; export type DownloadArtifactAttachmentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; /** * Attachment identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/attachments/{id}'; }; export type DownloadArtifactAttachmentErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact or attachment not found */ 404: ErrorResponse; /** * Attachment storage is not available */ 503: ErrorResponse; }; export type DownloadArtifactAttachmentError = DownloadArtifactAttachmentErrors[keyof DownloadArtifactAttachmentErrors]; export type DownloadArtifactAttachmentResponses = { /** * Attachment file stream */ 200: Blob | File; }; export type DownloadArtifactAttachmentResponse = DownloadArtifactAttachmentResponses[keyof DownloadArtifactAttachmentResponses]; export type ListArtifactVersionsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/versions'; }; export type ListArtifactVersionsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact not found */ 404: ErrorResponse; }; export type ListArtifactVersionsError = ListArtifactVersionsErrors[keyof ListArtifactVersionsErrors]; export type ListArtifactVersionsResponses = { /** * Artifact versions retrieved successfully */ 200: ArtifactVersionListResponse; }; export type ListArtifactVersionsResponse = ListArtifactVersionsResponses[keyof ListArtifactVersionsResponses]; export type GetArtifactVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; /** * Version number */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/versions/{version_number}'; }; export type GetArtifactVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact or version not found */ 404: ErrorResponse; }; export type GetArtifactVersionError = GetArtifactVersionErrors[keyof GetArtifactVersionErrors]; export type GetArtifactVersionResponses = { /** * Artifact version retrieved successfully */ 200: ContentVersion; }; export type GetArtifactVersionResponse = GetArtifactVersionResponses[keyof GetArtifactVersionResponses]; export type RestoreArtifactVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Artifact slug */ slug: string; /** * Version number to restore */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/artifacts/{project_id}/{slug}/versions/{version_number}/restore'; }; export type RestoreArtifactVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Artifact or version not found */ 404: ErrorResponse; }; export type RestoreArtifactVersionError = RestoreArtifactVersionErrors[keyof RestoreArtifactVersionErrors]; export type RestoreArtifactVersionResponses = { /** * Artifact restored successfully */ 200: Artifact; }; export type RestoreArtifactVersionResponse = RestoreArtifactVersionResponses[keyof RestoreArtifactVersionResponses]; export type SearchTeamResourcesData = { body: SearchRequest; path: { /** * Team ID */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/search'; }; export type SearchTeamResourcesErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * User is not a member of the team */ 403: ErrorResponse; }; export type SearchTeamResourcesError = SearchTeamResourcesErrors[keyof SearchTeamResourcesErrors]; export type SearchTeamResourcesResponses = { /** * Search results retrieved successfully */ 200: SearchResultsResponse; }; export type SearchTeamResourcesResponse = SearchTeamResourcesResponses[keyof SearchTeamResourcesResponses]; export type GetResourceAccessMetricsData = { body?: never; path: { /** * Team ID */ team_id: string; }; query: { /** * The resource type to report on (singular form). */ resource_type: 'prompt' | 'artifact' | 'blueprint' | 'memory' | 'project' | 'agent'; /** * The resource UUID. */ resource_id: string; /** * The reporting window. Defaults to 30d. */ range?: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; }; url: '/api/v1/{team_id}/resource-access-metrics'; }; export type GetResourceAccessMetricsErrors = { /** * Invalid request parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * User is not a member of the team */ 403: ErrorResponse; /** * Failed to retrieve resource access metrics */ 500: ErrorResponse; }; export type GetResourceAccessMetricsError = GetResourceAccessMetricsErrors[keyof GetResourceAccessMetricsErrors]; export type GetResourceAccessMetricsResponses = { /** * Resource access metrics retrieved successfully */ 200: ResourceAccessMetricsResponse; }; export type GetResourceAccessMetricsResponse = GetResourceAccessMetricsResponses[keyof GetResourceAccessMetricsResponses]; export type ListMemoriesData = { body?: never; path: { /** * Team ID */ team_id: string; }; query?: { /** * Filter to resources currently flagged stale by the team's freshness rules (epic #726). Omit for no freshness filtering. Returns 400 for any other value — a silently ignored filter would return the full list, which looks like a legitimate answer. */ freshness?: 'stale'; /** * Filter memories by project ID */ project_id?: string; /** * Search in memory text */ search?: string; /** * Filter by metadata as a JSON object of key to array of string values. Keys are combined with AND, values within a key with OR, and an empty array means "the key exists". Values match metadata stored as a scalar or as an array, and numeric/boolean values are matched by their string form. At most 10 keys, 25 values per key, key length 255, value length 512. Example: {"env":["prod","staging"],"team":["core"]} */ metadata?: string; /** * Filter by lifecycle status. When omitted, archived memories are hidden (active and draft are returned); an explicit value returns only that status. Returns 400 for unknown values. */ status?: 'active' | 'draft' | 'archived'; /** * Field to sort results by. Allowed: text, updated_at, created_at. Returns 400 for unknown values. */ sort_by?: 'text' | 'updated_at' | 'created_at'; /** * Sort direction (asc or desc, default desc) */ sort_order?: 'asc' | 'desc'; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/memories'; }; export type ListMemoriesErrors = { /** * Invalid query parameter (for example an unknown `status` or `sort_by` value, or a malformed `metadata` filter) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; }; export type ListMemoriesError = ListMemoriesErrors[keyof ListMemoriesErrors]; export type ListMemoriesResponses = { /** * Memories retrieved successfully */ 200: MemoryListResponse; }; export type ListMemoriesResponse = ListMemoriesResponses[keyof ListMemoriesResponses]; export type CreateMemoryData = { body: CreateMemoryRequest; path: { /** * Team ID */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/memories'; }; export type CreateMemoryErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; }; export type CreateMemoryError = CreateMemoryErrors[keyof CreateMemoryErrors]; export type CreateMemoryResponses = { /** * Memory created successfully */ 201: Memory; }; export type CreateMemoryResponse = CreateMemoryResponses[keyof CreateMemoryResponses]; export type DeleteMemoryData = { body?: never; path: { /** * Team ID */ team_id: string; /** * Memory ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/memories/{id}'; }; export type DeleteMemoryErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Memory not found */ 404: ErrorResponse; }; export type DeleteMemoryError = DeleteMemoryErrors[keyof DeleteMemoryErrors]; export type DeleteMemoryResponses = { /** * Memory deleted successfully */ 204: void; }; export type DeleteMemoryResponse = DeleteMemoryResponses[keyof DeleteMemoryResponses]; export type GetMemoryData = { body?: never; path: { /** * Team ID */ team_id: string; /** * Memory ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/memories/{id}'; }; export type GetMemoryErrors = { /** * Memory not found */ 404: ErrorResponse; }; export type GetMemoryError = GetMemoryErrors[keyof GetMemoryErrors]; export type GetMemoryResponses = { /** * Memory retrieved successfully */ 200: Memory; }; export type GetMemoryResponse = GetMemoryResponses[keyof GetMemoryResponses]; export type UpdateMemoryData = { body: UpdateMemoryRequest; path: { /** * Team ID */ team_id: string; /** * Memory ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/memories/{id}'; }; export type UpdateMemoryErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Memory not found */ 404: ErrorResponse; }; export type UpdateMemoryError = UpdateMemoryErrors[keyof UpdateMemoryErrors]; export type UpdateMemoryResponses = { /** * Memory updated successfully */ 200: Memory; }; export type UpdateMemoryResponse = UpdateMemoryResponses[keyof UpdateMemoryResponses]; export type ListMemoryVersionsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Memory ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/memories/{id}/versions'; }; export type ListMemoryVersionsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Memory not found */ 404: ErrorResponse; }; export type ListMemoryVersionsError = ListMemoryVersionsErrors[keyof ListMemoryVersionsErrors]; export type ListMemoryVersionsResponses = { /** * Memory versions retrieved successfully */ 200: MemoryVersionListResponse; }; export type ListMemoryVersionsResponse = ListMemoryVersionsResponses[keyof ListMemoryVersionsResponses]; export type GetMemoryVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Memory ID */ id: string; /** * Version number */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/memories/{id}/versions/{version_number}'; }; export type GetMemoryVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Memory or version not found */ 404: ErrorResponse; }; export type GetMemoryVersionError = GetMemoryVersionErrors[keyof GetMemoryVersionErrors]; export type GetMemoryVersionResponses = { /** * Memory version retrieved successfully */ 200: ContentVersion; }; export type GetMemoryVersionResponse = GetMemoryVersionResponses[keyof GetMemoryVersionResponses]; export type RestoreMemoryVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Memory ID */ id: string; /** * Version number to restore */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/memories/{id}/versions/{version_number}/restore'; }; export type RestoreMemoryVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Memory or version not found */ 404: ErrorResponse; }; export type RestoreMemoryVersionError = RestoreMemoryVersionErrors[keyof RestoreMemoryVersionErrors]; export type RestoreMemoryVersionResponses = { /** * Memory restored successfully */ 200: Memory; }; export type RestoreMemoryVersionResponse = RestoreMemoryVersionResponses[keyof RestoreMemoryVersionResponses]; export type GetProjectStatsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/projects/{slug}/stats'; }; export type GetProjectStatsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Project not found */ 404: ErrorResponse; }; export type GetProjectStatsError = GetProjectStatsErrors[keyof GetProjectStatsErrors]; export type GetProjectStatsResponses = { /** * Project statistics retrieved successfully */ 200: ProjectStatsResponse; }; export type GetProjectStatsResponse = GetProjectStatsResponses[keyof GetProjectStatsResponses]; export type GetProjectResourceCreationMetricsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project slug */ slug: string; }; query?: { /** * The reporting window. Defaults to 30d. */ range?: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; }; url: '/api/v1/{team_id}/projects/{slug}/resource-creation-metrics'; }; export type GetProjectResourceCreationMetricsErrors = { /** * Invalid request parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Project not found */ 404: ErrorResponse; }; export type GetProjectResourceCreationMetricsError = GetProjectResourceCreationMetricsErrors[keyof GetProjectResourceCreationMetricsErrors]; export type GetProjectResourceCreationMetricsResponses = { /** * Resource creation metrics retrieved successfully */ 200: ProjectResourceCreationMetricsResponse; }; export type GetProjectResourceCreationMetricsResponse = GetProjectResourceCreationMetricsResponses[keyof GetProjectResourceCreationMetricsResponses]; export type ListSpecLibrariesData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Filter to resources currently flagged stale by the team's freshness rules (epic #726). Omit for no freshness filtering. Returns 400 for any other value — a silently ignored filter would return the full list, which looks like a legitimate answer. */ freshness?: 'stale'; /** * Filter by project name */ project_name?: string; /** * Filter by project ID. On this team-scoped variant the backend reads it only when a project is not already selected via a path parameter (i.e. not on listSpecLibrariesByProject). */ project_id?: string; /** * Filter by status */ status?: 'active' | 'expired'; /** * Filter by type */ type?: 'general' | 'claude-code' | 'claude' | 'cursor' | 'codex'; /** * Filter by subtype category */ subtype?: 'sub-agents' | 'skills' | 'slash-commands' | 'others' | 'claude-md' | 'agents' | 'commands' | 'rules' | 'cursor-md' | 'agents-md'; /** * Search in title, description, and content */ search?: string; /** * Filter by metadata as a JSON object of key to array of string values. Keys are combined with AND, values within a key with OR, and an empty array means "the key exists". Values match metadata stored as a scalar or as an array, and numeric/boolean values are matched by their string form. At most 10 keys, 25 values per key, key length 255, value length 512. Example: {"env":["prod","staging"],"team":["core"]} */ metadata?: string; /** * Sort field */ sort_by?: 'created_at' | 'updated_at' | 'title'; /** * Sort order */ sort_order?: 'asc' | 'desc'; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/blueprints'; }; export type ListSpecLibrariesErrors = { /** * Invalid query parameter (for example a malformed `metadata` filter) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListSpecLibrariesError = ListSpecLibrariesErrors[keyof ListSpecLibrariesErrors]; export type ListSpecLibrariesResponses = { /** * Spec libraries retrieved successfully */ 200: BlueprintListResponse; }; export type ListSpecLibrariesResponse = ListSpecLibrariesResponses[keyof ListSpecLibrariesResponses]; export type CreateBlueprintData = { body: CreateBlueprintRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/blueprints'; }; export type CreateBlueprintErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * No permission to create blueprints in this team */ 403: ErrorResponse; /** * Spec library with same slug already exists in project */ 409: ErrorResponse; }; export type CreateBlueprintError = CreateBlueprintErrors[keyof CreateBlueprintErrors]; export type CreateBlueprintResponses = { /** * Spec library created successfully */ 201: Blueprint; }; export type CreateBlueprintResponse = CreateBlueprintResponses[keyof CreateBlueprintResponses]; export type GetBlueprintStatsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/blueprints/stats'; }; export type GetBlueprintStatsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetBlueprintStatsError = GetBlueprintStatsErrors[keyof GetBlueprintStatsErrors]; export type GetBlueprintStatsResponses = { /** * Spec library statistics retrieved successfully */ 200: BlueprintStatsResponse; }; export type GetBlueprintStatsResponse = GetBlueprintStatsResponses[keyof GetBlueprintStatsResponses]; export type ListSpecLibrariesByProjectData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project identifier (URL-encoded) */ project_id: string; }; query?: { /** * Filter to resources currently flagged stale by the team's freshness rules (epic #726). Omit for no freshness filtering. Returns 400 for any other value — a silently ignored filter would return the full list, which looks like a legitimate answer. */ freshness?: 'stale'; /** * Filter by status */ status?: 'active' | 'expired'; /** * Filter by type */ type?: 'general' | 'claude-code' | 'claude' | 'cursor' | 'codex'; /** * Filter by subtype category */ subtype?: 'sub-agents' | 'skills' | 'slash-commands' | 'others' | 'claude-md' | 'agents' | 'commands' | 'rules' | 'cursor-md' | 'agents-md'; /** * Search in title, description, and content */ search?: string; /** * Filter by metadata as a JSON object of key to array of string values. Keys are combined with AND, values within a key with OR, and an empty array means "the key exists". Values match metadata stored as a scalar or as an array, and numeric/boolean values are matched by their string form. At most 10 keys, 25 values per key, key length 255, value length 512. Example: {"env":["prod","staging"],"team":["core"]} */ metadata?: string; /** * Sort field */ sort_by?: 'created_at' | 'updated_at' | 'title'; /** * Sort order */ sort_order?: 'asc' | 'desc'; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/blueprints/{project_id}'; }; export type ListSpecLibrariesByProjectErrors = { /** * Invalid project name encoding */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListSpecLibrariesByProjectError = ListSpecLibrariesByProjectErrors[keyof ListSpecLibrariesByProjectErrors]; export type ListSpecLibrariesByProjectResponses = { /** * Spec libraries retrieved successfully */ 200: BlueprintListResponse; }; export type ListSpecLibrariesByProjectResponse = ListSpecLibrariesByProjectResponses[keyof ListSpecLibrariesByProjectResponses]; export type DeleteBlueprintData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project identifier (URL-encoded) */ project_id: string; /** * Spec library slug (URL-encoded) */ slug: string; }; query?: never; url: '/api/v1/{team_id}/blueprints/{project_id}/{slug}'; }; export type DeleteBlueprintErrors = { /** * Invalid parameter encoding */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Spec library not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type DeleteBlueprintError = DeleteBlueprintErrors[keyof DeleteBlueprintErrors]; export type DeleteBlueprintResponses = { /** * Spec library deleted successfully */ 204: void; }; export type DeleteBlueprintResponse = DeleteBlueprintResponses[keyof DeleteBlueprintResponses]; export type GetBlueprintData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project identifier (URL-encoded) */ project_id: string; /** * Spec library slug (URL-encoded) */ slug: string; }; query?: never; url: '/api/v1/{team_id}/blueprints/{project_id}/{slug}'; }; export type GetBlueprintErrors = { /** * Invalid parameter encoding */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Spec library not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetBlueprintError = GetBlueprintErrors[keyof GetBlueprintErrors]; export type GetBlueprintResponses = { /** * Spec library retrieved successfully */ 200: BlueprintDetail; }; export type GetBlueprintResponse = GetBlueprintResponses[keyof GetBlueprintResponses]; export type UpdateBlueprintData = { body: UpdateBlueprintRequest; path: { /** * Team identifier */ team_id: string; /** * Project identifier (URL-encoded) */ project_id: string; /** * Spec library slug (URL-encoded) */ slug: string; }; query?: never; url: '/api/v1/{team_id}/blueprints/{project_id}/{slug}'; }; export type UpdateBlueprintErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Resource limit exceeded */ 403: ErrorResponse; /** * Spec library not found */ 404: ErrorResponse; /** * Spec library with same slug already exists in project */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateBlueprintError = UpdateBlueprintErrors[keyof UpdateBlueprintErrors]; export type UpdateBlueprintResponses = { /** * Spec library updated successfully */ 200: Blueprint; }; export type UpdateBlueprintResponse = UpdateBlueprintResponses[keyof UpdateBlueprintResponses]; export type ListBlueprintVersionsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Blueprint slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/blueprints/{project_id}/{slug}/versions'; }; export type ListBlueprintVersionsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Blueprint not found */ 404: ErrorResponse; }; export type ListBlueprintVersionsError = ListBlueprintVersionsErrors[keyof ListBlueprintVersionsErrors]; export type ListBlueprintVersionsResponses = { /** * Blueprint versions retrieved successfully */ 200: BlueprintVersionListResponse; }; export type ListBlueprintVersionsResponse = ListBlueprintVersionsResponses[keyof ListBlueprintVersionsResponses]; export type GetBlueprintVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Blueprint slug */ slug: string; /** * Version number */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/blueprints/{project_id}/{slug}/versions/{version_number}'; }; export type GetBlueprintVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Blueprint or version not found */ 404: ErrorResponse; }; export type GetBlueprintVersionError = GetBlueprintVersionErrors[keyof GetBlueprintVersionErrors]; export type GetBlueprintVersionResponses = { /** * Blueprint version retrieved successfully */ 200: ContentVersion; }; export type GetBlueprintVersionResponse = GetBlueprintVersionResponses[keyof GetBlueprintVersionResponses]; export type RestoreBlueprintVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * UUID of the project */ project_id: string; /** * Blueprint slug */ slug: string; /** * Version number to restore */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/blueprints/{project_id}/{slug}/versions/{version_number}/restore'; }; export type RestoreBlueprintVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Blueprint or version not found */ 404: ErrorResponse; }; export type RestoreBlueprintVersionError = RestoreBlueprintVersionErrors[keyof RestoreBlueprintVersionErrors]; export type RestoreBlueprintVersionResponses = { /** * Blueprint restored successfully */ 200: Blueprint; }; export type RestoreBlueprintVersionResponse = RestoreBlueprintVersionResponses[keyof RestoreBlueprintVersionResponses]; export type ListPromptsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Filter to resources currently flagged stale by the team's freshness rules (epic #726). Omit for no freshness filtering. Returns 400 for any other value — a silently ignored filter would return the full list, which looks like a legitimate answer. */ freshness?: 'stale'; /** * Page number for pagination */ page?: number; /** * Number of items per page */ limit?: number; /** * Search term to filter prompts by name or description */ search?: string; /** * Filter by prompt status */ status?: 'draft' | 'published'; /** * Comma-separated list of labels to filter by */ labels?: string; /** * Filter by project ID */ project_id?: string; /** * Filter by MCP exposure flag. Non-boolean values are ignored (no filter applied). */ mcp_expose?: boolean; /** * Filter by share status (prompts with an active share). Non-boolean values are ignored (no filter applied). */ shared?: boolean; /** * Field to sort results by. Allowed: name, status, updated_at, created_at. Returns 400 for unknown values. */ sort_by?: 'name' | 'status' | 'updated_at' | 'created_at'; /** * Sort direction (asc or desc, default desc) */ sort_order?: 'asc' | 'desc'; }; url: '/api/v1/{team_id}/prompts'; }; export type ListPromptsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; }; export type ListPromptsError = ListPromptsErrors[keyof ListPromptsErrors]; export type ListPromptsResponses = { /** * List of prompts retrieved successfully */ 200: PromptListEnvelope; }; export type ListPromptsResponse = ListPromptsResponses[keyof ListPromptsResponses]; export type CreatePromptData = { body: CreatePromptRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/prompts'; }; export type CreatePromptErrors = { /** * Invalid request (validation error) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Conflict (prompt with slug already exists) */ 409: ErrorResponse; }; export type CreatePromptError = CreatePromptErrors[keyof CreatePromptErrors]; export type CreatePromptResponses = { /** * Prompt created successfully */ 201: Prompt; }; export type CreatePromptResponse = CreatePromptResponses[keyof CreatePromptResponses]; export type GetPromptLabelsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/prompts/labels'; }; export type GetPromptLabelsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; }; export type GetPromptLabelsError = GetPromptLabelsErrors[keyof GetPromptLabelsErrors]; export type GetPromptLabelsResponses = { /** * Labels retrieved successfully */ 200: PromptLabelsEnvelope; }; export type GetPromptLabelsResponse = GetPromptLabelsResponses[keyof GetPromptLabelsResponses]; export type DeletePromptData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}'; }; export type DeletePromptErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type DeletePromptError = DeletePromptErrors[keyof DeletePromptErrors]; export type DeletePromptResponses = { /** * Prompt deleted successfully */ 204: void; }; export type DeletePromptResponse = DeletePromptResponses[keyof DeletePromptResponses]; export type GetPromptData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}'; }; export type GetPromptErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type GetPromptError = GetPromptErrors[keyof GetPromptErrors]; export type GetPromptResponses = { /** * Prompt retrieved successfully */ 200: Prompt; }; export type GetPromptResponse = GetPromptResponses[keyof GetPromptResponses]; export type UpdatePromptData = { body: UpdatePromptRequest; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}'; }; export type UpdatePromptErrors = { /** * Invalid request (validation error) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; /** * Conflict (slug already exists) */ 409: ErrorResponse; }; export type UpdatePromptError = UpdatePromptErrors[keyof UpdatePromptErrors]; export type UpdatePromptResponses = { /** * Prompt updated successfully */ 200: Prompt; }; export type UpdatePromptResponse = UpdatePromptResponses[keyof UpdatePromptResponses]; export type GetPromptPlaceholdersData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/placeholders'; }; export type GetPromptPlaceholdersErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type GetPromptPlaceholdersError = GetPromptPlaceholdersErrors[keyof GetPromptPlaceholdersErrors]; export type GetPromptPlaceholdersResponses = { /** * Placeholders retrieved successfully */ 200: PromptPlaceholdersResponse; }; export type GetPromptPlaceholdersResponse = GetPromptPlaceholdersResponses[keyof GetPromptPlaceholdersResponses]; export type GetPromptDependenciesData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/dependencies'; }; export type GetPromptDependenciesErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type GetPromptDependenciesError = GetPromptDependenciesErrors[keyof GetPromptDependenciesErrors]; export type GetPromptDependenciesResponses = { /** * Dependencies retrieved successfully */ 200: PromptDependenciesResponse; }; export type GetPromptDependenciesResponse = GetPromptDependenciesResponses[keyof GetPromptDependenciesResponses]; export type RenderPromptData = { body: RenderPromptRequest; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/render'; }; export type RenderPromptErrors = { /** * Invalid request */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type RenderPromptError = RenderPromptErrors[keyof RenderPromptErrors]; export type RenderPromptResponses = { /** * Prompt rendered successfully */ 200: RenderPromptResponse; }; export type RenderPromptResponse2 = RenderPromptResponses[keyof RenderPromptResponses]; export type DeletePromptShareData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/share'; }; export type DeletePromptShareErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt or share not found */ 404: ErrorResponse; }; export type DeletePromptShareError = DeletePromptShareErrors[keyof DeletePromptShareErrors]; export type DeletePromptShareResponses = { /** * Share deleted successfully */ 204: void; }; export type DeletePromptShareResponse = DeletePromptShareResponses[keyof DeletePromptShareResponses]; export type GetPromptShareData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/share'; }; export type GetPromptShareErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt or share not found */ 404: ErrorResponse; }; export type GetPromptShareError = GetPromptShareErrors[keyof GetPromptShareErrors]; export type GetPromptShareResponses = { /** * Share details retrieved successfully */ 200: ShareResponse; }; export type GetPromptShareResponse = GetPromptShareResponses[keyof GetPromptShareResponses]; export type CreatePromptShareData = { body: CreateShareRequest; path: { /** * Team identifier */ team_id: string; /** * Prompt slug identifier */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/share'; }; export type CreatePromptShareErrors = { /** * Invalid request (e.g., restricted share without emails) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type CreatePromptShareError = CreatePromptShareErrors[keyof CreatePromptShareErrors]; export type CreatePromptShareResponses = { /** * Share created or updated successfully */ 200: ShareResponse; }; export type CreatePromptShareResponse = CreatePromptShareResponses[keyof CreatePromptShareResponses]; export type ListPromptVersionsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug */ slug: string; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/versions'; }; export type ListPromptVersionsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type ListPromptVersionsError = ListPromptVersionsErrors[keyof ListPromptVersionsErrors]; export type ListPromptVersionsResponses = { /** * Prompt versions retrieved successfully */ 200: PromptVersionListResponse; }; export type ListPromptVersionsResponse = ListPromptVersionsResponses[keyof ListPromptVersionsResponses]; export type GetPromptVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug */ slug: string; /** * Version number */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/versions/{version_number}'; }; export type GetPromptVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Prompt or version not found */ 404: ErrorResponse; }; export type GetPromptVersionError = GetPromptVersionErrors[keyof GetPromptVersionErrors]; export type GetPromptVersionResponses = { /** * Prompt version retrieved successfully */ 200: ContentVersion; }; export type GetPromptVersionResponse = GetPromptVersionResponses[keyof GetPromptVersionResponses]; export type RestorePromptVersionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Prompt slug */ slug: string; /** * Version number to restore */ version_number: number; }; query?: never; url: '/api/v1/{team_id}/prompts/{slug}/versions/{version_number}/restore'; }; export type RestorePromptVersionErrors = { /** * Invalid version_number */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Prompt or version not found */ 404: ErrorResponse; }; export type RestorePromptVersionError = RestorePromptVersionErrors[keyof RestorePromptVersionErrors]; export type RestorePromptVersionResponses = { /** * Prompt restored successfully */ 200: Prompt; }; export type RestorePromptVersionResponse = RestorePromptVersionResponses[keyof RestorePromptVersionResponses]; export type GetPromptGalleryCategoriesData = { body?: never; path?: never; query?: never; url: '/api/v1/prompt-gallery/categories'; }; export type GetPromptGalleryCategoriesErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type GetPromptGalleryCategoriesError = GetPromptGalleryCategoriesErrors[keyof GetPromptGalleryCategoriesErrors]; export type GetPromptGalleryCategoriesResponses = { /** * Categories retrieved successfully */ 200: PromptGalleryCategoryList; }; export type GetPromptGalleryCategoriesResponse = GetPromptGalleryCategoriesResponses[keyof GetPromptGalleryCategoriesResponses]; export type ListPromptGalleryPromptsData = { body?: never; path?: never; query?: { /** * Filter by category */ category?: string; /** * Search in title and description */ search?: string; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/prompt-gallery/prompts'; }; export type ListPromptGalleryPromptsErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type ListPromptGalleryPromptsError = ListPromptGalleryPromptsErrors[keyof ListPromptGalleryPromptsErrors]; export type ListPromptGalleryPromptsResponses = { /** * Prompts retrieved successfully */ 200: PromptGalleryListResponse; }; export type ListPromptGalleryPromptsResponse = ListPromptGalleryPromptsResponses[keyof ListPromptGalleryPromptsResponses]; export type GetPromptGalleryPromptData = { body?: never; path: { /** * Prompt ID */ id: string; }; query?: never; url: '/api/v1/prompt-gallery/prompts/{id}'; }; export type GetPromptGalleryPromptErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type GetPromptGalleryPromptError = GetPromptGalleryPromptErrors[keyof GetPromptGalleryPromptErrors]; export type GetPromptGalleryPromptResponses = { /** * Prompt retrieved successfully */ 200: PromptGalleryTemplate; }; export type GetPromptGalleryPromptResponse = GetPromptGalleryPromptResponses[keyof GetPromptGalleryPromptResponses]; export type TrackPromptGalleryUsageData = { body?: never; path: { /** * Prompt ID */ id: string; }; query?: never; url: '/api/v1/prompt-gallery/prompts/{id}/use'; }; export type TrackPromptGalleryUsageErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Prompt not found */ 404: ErrorResponse; }; export type TrackPromptGalleryUsageError = TrackPromptGalleryUsageErrors[keyof TrackPromptGalleryUsageErrors]; export type TrackPromptGalleryUsageResponses = { /** * Usage tracked successfully */ 200: SuccessResponse; }; export type TrackPromptGalleryUsageResponse = TrackPromptGalleryUsageResponses[keyof TrackPromptGalleryUsageResponses]; export type GetSharedPromptData = { body?: never; path: { /** * Share token */ token: string; }; query?: never; url: '/api/v1/shared/prompts/{token}'; }; export type GetSharedPromptErrors = { /** * Authentication required for restricted share */ 401: ErrorResponse; /** * Access denied (share disabled, expired, or email not in access list) */ 403: ErrorResponse; /** * Shared prompt not found */ 404: ErrorResponse; }; export type GetSharedPromptError = GetSharedPromptErrors[keyof GetSharedPromptErrors]; export type GetSharedPromptResponses = { /** * Shared prompt retrieved successfully */ 200: SharedPromptResponse; }; export type GetSharedPromptResponse = GetSharedPromptResponses[keyof GetSharedPromptResponses]; export type GetUsageAndGrowthData = { body?: never; path?: never; query?: { /** * Filter data from this date (YYYY-MM-DD format). Both 'from' and 'to' must be provided together. */ from?: string; /** * Filter data until this date (YYYY-MM-DD format). Both 'from' and 'to' must be provided together. */ to?: string; }; url: '/bo/v1/reports/usage-and-growth'; }; export type GetUsageAndGrowthErrors = { /** * Invalid request parameters (e.g., invalid date format, 'to' before 'from') */ 400: ErrorResponse; /** * Unauthorized - Missing or invalid back office admin API key */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetUsageAndGrowthError = GetUsageAndGrowthErrors[keyof GetUsageAndGrowthErrors]; export type GetUsageAndGrowthResponses = { /** * Usage and growth data retrieved successfully */ 200: UsageAndGrowthResponse; }; export type GetUsageAndGrowthResponse = GetUsageAndGrowthResponses[keyof GetUsageAndGrowthResponses]; export type GetGitHubStatusData = { body?: never; path: { /** * Team ID (UUID) */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/status'; }; export type GetGitHubStatusErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - user does not have access to this team */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetGitHubStatusError = GetGitHubStatusErrors[keyof GetGitHubStatusErrors]; export type GetGitHubStatusResponses = { /** * GitHub installation status retrieved successfully */ 200: GitHubInstallationStatus; }; export type GetGitHubStatusResponse = GetGitHubStatusResponses[keyof GetGitHubStatusResponses]; export type GetGitHubInstallUrlData = { body?: never; path: { /** * Team ID (UUID) */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/install-url'; }; export type GetGitHubInstallUrlErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - user does not have access to this team, or is not a team owner/admin */ 403: ErrorResponse; /** * Conflict - the team has no GitHub App configured, so there is no App slug to build an install URL from. Register the team's App first. */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetGitHubInstallUrlError = GetGitHubInstallUrlErrors[keyof GetGitHubInstallUrlErrors]; export type GetGitHubInstallUrlResponses = { /** * Install URL generated successfully */ 200: GitHubInstallUrl; }; export type GetGitHubInstallUrlResponse = GetGitHubInstallUrlResponses[keyof GetGitHubInstallUrlResponses]; export type HandleGitHubCallbackData = { body: { /** * GitHub App installation ID from the callback URL */ installation_id: number; /** * Setup action reported by GitHub on the callback URL (e.g. "install"). Accepted for forward compatibility but currently ignored server-side. */ setup_action?: string; /** * HMAC-signed state parameter from the install URL (CSRF protection). It is bound to the team's GitHub App config, so a state minted before the team replaced or rotated its App is no longer redeemable. */ state: string; /** * OAuth authorization code from GitHub's post-install redirect. Exchanged server-side for a user access token to verify the caller has access to the installation on GitHub. */ code: string; }; path: { /** * Team ID (UUID) */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/callback'; }; export type HandleGitHubCallbackErrors = { /** * Invalid request body, missing required fields, an invalid/expired state parameter, or a state bound to a different installation or GitHub App than the team's current one */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - state does not match team, the caller is not a team owner/admin, or the caller has no access to the submitted GitHub App installation on GitHub */ 403: ErrorResponse; /** * Conflict - this GitHub organization is already connected to another team, or the team has no GitHub App configured to complete the installation against */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; /** * GitHub App user authorization is not configured on this instance, so caller authority cannot be verified and the installation is not connected */ 503: ErrorResponse; }; export type HandleGitHubCallbackError = HandleGitHubCallbackErrors[keyof HandleGitHubCallbackErrors]; export type HandleGitHubCallbackResponses = { /** * GitHub App installation connected successfully */ 201: GitHubCallbackResponse; }; export type HandleGitHubCallbackResponse = HandleGitHubCallbackResponses[keyof HandleGitHubCallbackResponses]; export type ListGitHubRepositoriesData = { body?: never; path: { /** * Team ID (UUID) */ team_id: string; }; query?: { /** * Page number for pagination (1-based) */ page?: number; }; url: '/api/v1/{team_id}/integrations/github/repositories'; }; export type ListGitHubRepositoriesErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - user does not have access to this team */ 403: ErrorResponse; /** * GitHub App not installed for this team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListGitHubRepositoriesError = ListGitHubRepositoriesErrors[keyof ListGitHubRepositoriesErrors]; export type ListGitHubRepositoriesResponses = { /** * Repositories listed successfully */ 200: GitHubRepositoriesResponse; }; export type ListGitHubRepositoriesResponse = ListGitHubRepositoriesResponses[keyof ListGitHubRepositoriesResponses]; export type ImportGitHubProjectData = { body?: never; path: { /** * Team ID (UUID) */ team_id: string; /** * GitHub repository ID */ repo_id: number; }; query?: never; url: '/api/v1/{team_id}/integrations/github/repositories/{repo_id}/import-project'; }; export type ImportGitHubProjectErrors = { /** * Invalid repository ID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - user does not have access to this team */ 403: ErrorResponse; /** * GitHub App not installed for this team or repository not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ImportGitHubProjectError = ImportGitHubProjectErrors[keyof ImportGitHubProjectErrors]; export type ImportGitHubProjectResponses = { /** * Project already exists — returned without creating a new one */ 200: GitHubImportProjectResultResponse; /** * Project created successfully from the GitHub repository */ 201: GitHubImportProjectResultResponse; }; export type ImportGitHubProjectResponse = ImportGitHubProjectResponses[keyof ImportGitHubProjectResponses]; export type ImportGitHubBlueprintsData = { body: { /** * GitHub repository ID to import blueprints from */ repository_id: number; }; path: { /** * Team ID (UUID) */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/import-blueprints'; }; export type ImportGitHubBlueprintsErrors = { /** * Invalid request body or missing repository_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - user does not have access to this team */ 403: ErrorResponse; /** * GitHub App not installed for this team or repository not found */ 404: ErrorResponse; /** * Precondition Failed - no project exists for this repository; import the repository as a project first */ 412: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ImportGitHubBlueprintsError = ImportGitHubBlueprintsErrors[keyof ImportGitHubBlueprintsErrors]; export type ImportGitHubBlueprintsResponses = { /** * Import completed — check the report for per-file results */ 200: BlueprintImportReport; }; export type ImportGitHubBlueprintsResponse = ImportGitHubBlueprintsResponses[keyof ImportGitHubBlueprintsResponses]; export type DisconnectGitHubData = { body?: never; path: { /** * Team ID (UUID) */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/disconnect'; }; export type DisconnectGitHubErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - user does not have access to this team */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type DisconnectGitHubError = DisconnectGitHubErrors[keyof DisconnectGitHubErrors]; export type DisconnectGitHubResponses = { /** * GitHub installation disconnected successfully */ 204: void; }; export type DisconnectGitHubResponse = DisconnectGitHubResponses[keyof DisconnectGitHubResponses]; export type HandleGitHubWebhookData = { /** * GitHub webhook event payload (varies by event type) */ body: { [key: string]: unknown; }; path?: never; query?: never; url: '/api/v1/webhooks/github'; }; export type HandleGitHubWebhookErrors = { /** * Endpoint retired; use the team's per-App webhook URL */ 410: ErrorResponse; }; export type HandleGitHubWebhookError = HandleGitHubWebhookErrors[keyof HandleGitHubWebhookErrors]; export type HandleGitHubWebhookByTokenData = { /** * GitHub webhook event payload (varies by event type) */ body: { [key: string]: unknown; }; path: { /** * Opaque routing token identifying which team's GitHub App this delivery belongs to. Minted as unpadded URL-safe base64, so it needs no percent-encoding. Treat it as a secret: it selects the secret the signature is verified against, and it is redacted from access logs. */ token: string; }; query?: never; url: '/api/v1/webhooks/github/{token}'; }; export type HandleGitHubWebhookByTokenErrors = { /** * Unreadable body, unparseable payload, or missing installation reference */ 400: ErrorResponse; /** * Missing or invalid `X-Hub-Signature-256` */ 401: ErrorResponse; /** * Unknown or malformed routing token (deliberately indistinguishable) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type HandleGitHubWebhookByTokenError = HandleGitHubWebhookByTokenErrors[keyof HandleGitHubWebhookByTokenErrors]; export type HandleGitHubWebhookByTokenResponses = { /** * Delivery accepted (or already processed — dedup by delivery id) */ 200: unknown; }; export type ListFeedsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Search in feed name and description */ search?: string; /** * Page number (default 1) */ page?: number; /** * Items per page (default 20, max 100) */ limit?: number; }; url: '/api/v1/{team_id}/feeds'; }; export type ListFeedsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; }; export type ListFeedsError = ListFeedsErrors[keyof ListFeedsErrors]; export type ListFeedsResponses = { /** * Feeds retrieved successfully */ 200: FeedListResponse; }; export type ListFeedsResponse = ListFeedsResponses[keyof ListFeedsResponses]; export type CreateFeedData = { body: CreateFeedRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/feeds'; }; export type CreateFeedErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * A feed with that name already exists in this team */ 409: ErrorResponse; }; export type CreateFeedError = CreateFeedErrors[keyof CreateFeedErrors]; export type CreateFeedResponses = { /** * Feed created successfully */ 201: Feed; }; export type CreateFeedResponse = CreateFeedResponses[keyof CreateFeedResponses]; export type DeleteFeedData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed identifier */ feed_id: string; }; query?: never; url: '/api/v1/{team_id}/feeds/{feed_id}'; }; export type DeleteFeedErrors = { /** * Invalid feed_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed not found */ 404: ErrorResponse; }; export type DeleteFeedError = DeleteFeedErrors[keyof DeleteFeedErrors]; export type DeleteFeedResponses = { /** * Feed deleted successfully */ 204: void; }; export type DeleteFeedResponse = DeleteFeedResponses[keyof DeleteFeedResponses]; export type GetFeedData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed identifier */ feed_id: string; }; query?: never; url: '/api/v1/{team_id}/feeds/{feed_id}'; }; export type GetFeedErrors = { /** * Invalid feed_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed not found */ 404: ErrorResponse; }; export type GetFeedError = GetFeedErrors[keyof GetFeedErrors]; export type GetFeedResponses = { /** * Feed retrieved successfully */ 200: Feed; }; export type GetFeedResponse = GetFeedResponses[keyof GetFeedResponses]; export type UpdateFeedData = { body: UpdateFeedRequest; path: { /** * Team identifier */ team_id: string; /** * Feed identifier */ feed_id: string; }; query?: never; url: '/api/v1/{team_id}/feeds/{feed_id}'; }; export type UpdateFeedErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed not found */ 404: ErrorResponse; /** * A feed with that name already exists in this team */ 409: ErrorResponse; }; export type UpdateFeedError = UpdateFeedErrors[keyof UpdateFeedErrors]; export type UpdateFeedResponses = { /** * Feed updated successfully */ 200: Feed; }; export type UpdateFeedResponse = UpdateFeedResponses[keyof UpdateFeedResponses]; export type ListFeedItemsByFeedData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed identifier */ feed_id: string; }; query?: { /** * Filter by project ID */ project_id?: string; /** * Filter by AI assistant name */ ai_assistant_name?: string; /** * Search in feed item title and content (case-insensitive substring) */ search?: string; /** * Filter by archived status: 'true' (archived only), 'false' (active only, default), 'all' */ archived?: 'true' | 'false' | 'all'; /** * Page number (default 1) */ page?: number; /** * Items per page (default 20, max 100) */ limit?: number; }; url: '/api/v1/{team_id}/feeds/{feed_id}/items'; }; export type ListFeedItemsByFeedErrors = { /** * Invalid feed_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; }; export type ListFeedItemsByFeedError = ListFeedItemsByFeedErrors[keyof ListFeedItemsByFeedErrors]; export type ListFeedItemsByFeedResponses = { /** * Feed items retrieved successfully */ 200: FeedItemListResponse; }; export type ListFeedItemsByFeedResponse = ListFeedItemsByFeedResponses[keyof ListFeedItemsByFeedResponses]; export type CreateFeedItemData = { body: CreateFeedItemRequest; path: { /** * Team identifier */ team_id: string; /** * Feed identifier */ feed_id: string; }; query?: never; url: '/api/v1/{team_id}/feeds/{feed_id}/items'; }; export type CreateFeedItemErrors = { /** * Invalid request data or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member or project belongs to a different team */ 403: ErrorResponse; }; export type CreateFeedItemError = CreateFeedItemErrors[keyof CreateFeedItemErrors]; export type CreateFeedItemResponses = { /** * Feed item created successfully */ 201: FeedItem; }; export type CreateFeedItemResponse = CreateFeedItemResponses[keyof CreateFeedItemResponses]; export type ListFeedItemsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Filter by feed ID */ feed_id?: string; /** * Filter by project ID */ project_id?: string; /** * Filter by AI assistant name */ ai_assistant_name?: string; /** * Search in feed item title and content (case-insensitive substring) */ search?: string; /** * Filter by archived status: 'true' (archived only), 'false' (active only, default), 'all' */ archived?: 'true' | 'false' | 'all'; /** * Page number (default 1) */ page?: number; /** * Items per page (default 20, max 100) */ limit?: number; }; url: '/api/v1/{team_id}/feed-items'; }; export type ListFeedItemsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; }; export type ListFeedItemsError = ListFeedItemsErrors[keyof ListFeedItemsErrors]; export type ListFeedItemsResponses = { /** * Feed items retrieved successfully */ 200: FeedItemListResponse; }; export type ListFeedItemsResponse = ListFeedItemsResponses[keyof ListFeedItemsResponses]; export type DeleteFeedItemData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed item identifier */ item_id: string; }; query?: never; url: '/api/v1/{team_id}/feed-items/{item_id}'; }; export type DeleteFeedItemErrors = { /** * Invalid item_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — caller is not a team member, or is not the item's poster, owner, or admin */ 403: ErrorResponse; /** * Feed item not found */ 404: ErrorResponse; }; export type DeleteFeedItemError = DeleteFeedItemErrors[keyof DeleteFeedItemErrors]; export type DeleteFeedItemResponses = { /** * Feed item deleted successfully */ 204: void; }; export type DeleteFeedItemResponse = DeleteFeedItemResponses[keyof DeleteFeedItemResponses]; export type GetFeedItemData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed item identifier */ item_id: string; }; query?: never; url: '/api/v1/{team_id}/feed-items/{item_id}'; }; export type GetFeedItemErrors = { /** * Invalid item_id format, or team_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed item not found */ 404: ErrorResponse; }; export type GetFeedItemError = GetFeedItemErrors[keyof GetFeedItemErrors]; export type GetFeedItemResponses = { /** * Feed item retrieved successfully */ 200: FeedItem; }; export type GetFeedItemResponse = GetFeedItemResponses[keyof GetFeedItemResponses]; export type ArchiveFeedItemData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed item identifier */ item_id: string; }; query?: never; url: '/api/v1/{team_id}/feed-items/{item_id}/archive'; }; export type ArchiveFeedItemErrors = { /** * Invalid item_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed item not found */ 404: ErrorResponse; }; export type ArchiveFeedItemError = ArchiveFeedItemErrors[keyof ArchiveFeedItemErrors]; export type ArchiveFeedItemResponses = { /** * Feed item archived successfully */ 204: void; }; export type ArchiveFeedItemResponse = ArchiveFeedItemResponses[keyof ArchiveFeedItemResponses]; export type UnarchiveFeedItemData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed item identifier */ item_id: string; }; query?: never; url: '/api/v1/{team_id}/feed-items/{item_id}/unarchive'; }; export type UnarchiveFeedItemErrors = { /** * Invalid item_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed item not found */ 404: ErrorResponse; }; export type UnarchiveFeedItemError = UnarchiveFeedItemErrors[keyof UnarchiveFeedItemErrors]; export type UnarchiveFeedItemResponses = { /** * Feed item unarchived successfully */ 204: void; }; export type UnarchiveFeedItemResponse = UnarchiveFeedItemResponses[keyof UnarchiveFeedItemResponses]; export type GetInvitationByTokenData = { body?: never; path: { /** * Opaque invitation token from the invitation email link */ token: string; }; query?: never; url: '/api/v1/invitations/{token}'; }; export type GetInvitationByTokenErrors = { /** * Authentication required */ 401: ErrorResponse; /** * Invitation not found for the given token */ 404: ErrorResponse; /** * Invitation has already been accepted, rejected, or revoked */ 409: ErrorResponse; /** * Invitation has expired */ 410: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetInvitationByTokenError = GetInvitationByTokenErrors[keyof GetInvitationByTokenErrors]; export type GetInvitationByTokenResponses = { /** * Invitation details retrieved successfully */ 200: InvitationDetailsResponse; }; export type GetInvitationByTokenResponse = GetInvitationByTokenResponses[keyof GetInvitationByTokenResponses]; export type ListAgentsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Filter by agent status */ status?: 'active' | 'paused' | 'error'; /** * Search in agent name and description */ search?: string; /** * Sort field */ sort_by?: 'name' | 'status' | 'updated_at' | 'created_at' | 'last_run' | 'success_rate'; /** * Sort order */ sort_order?: 'asc' | 'desc'; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/agents'; }; export type ListAgentsErrors = { /** * Invalid sort_by value or invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListAgentsError = ListAgentsErrors[keyof ListAgentsErrors]; export type ListAgentsResponses = { /** * Agents retrieved successfully */ 200: AgentListResponse; }; export type ListAgentsResponse = ListAgentsResponses[keyof ListAgentsResponses]; export type CreateAgentData = { body: CreateAgentRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/agents'; }; export type CreateAgentErrors = { /** * Invalid request body, validation error, or invalid/unfetchable agent card (4xx from the card host) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * An agent with that name already exists for this user */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; /** * Agent card host unreachable or returned a server error */ 502: ErrorResponse; }; export type CreateAgentError = CreateAgentErrors[keyof CreateAgentErrors]; export type CreateAgentResponses = { /** * Agent created successfully */ 201: Agent; }; export type CreateAgentResponse = CreateAgentResponses[keyof CreateAgentResponses]; export type PreviewAgentCardData = { body: PreviewAgentCardRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/agents/preview-card'; }; export type PreviewAgentCardErrors = { /** * Invalid request body, missing card_url, or invalid/unfetchable agent card (4xx from the card host) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent card host unreachable or returned a server error */ 502: ErrorResponse; }; export type PreviewAgentCardError = PreviewAgentCardErrors[keyof PreviewAgentCardErrors]; export type PreviewAgentCardResponses = { /** * Agent card fetched successfully */ 200: AgentCard; }; export type PreviewAgentCardResponse = PreviewAgentCardResponses[keyof PreviewAgentCardResponses]; export type GetAgentStatsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/agents/stats'; }; export type GetAgentStatsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAgentStatsError = GetAgentStatsErrors[keyof GetAgentStatsErrors]; export type GetAgentStatsResponses = { /** * Agent statistics retrieved successfully */ 200: AgentStatsResponse; }; export type GetAgentStatsResponse = GetAgentStatsResponses[keyof GetAgentStatsResponses]; export type DeleteAgentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/{id}'; }; export type DeleteAgentErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type DeleteAgentError = DeleteAgentErrors[keyof DeleteAgentErrors]; export type DeleteAgentResponses = { /** * Agent deleted successfully */ 204: void; }; export type DeleteAgentResponse = DeleteAgentResponses[keyof DeleteAgentResponses]; export type GetAgentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/{id}'; }; export type GetAgentErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAgentError = GetAgentErrors[keyof GetAgentErrors]; export type GetAgentResponses = { /** * Agent retrieved successfully */ 200: Agent; }; export type GetAgentResponse = GetAgentResponses[keyof GetAgentResponses]; export type UpdateAgentData = { body: UpdateAgentRequest; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/{id}'; }; export type UpdateAgentErrors = { /** * Invalid request body, validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found */ 404: ErrorResponse; /** * An agent with that name already exists for this user */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateAgentError = UpdateAgentErrors[keyof UpdateAgentErrors]; export type UpdateAgentResponses = { /** * Agent updated successfully */ 200: Agent; }; export type UpdateAgentResponse = UpdateAgentResponses[keyof UpdateAgentResponses]; export type UpdateAgentCredentialsData = { body: UpdateAgentCredentialsRequest; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/{id}/credentials'; }; export type UpdateAgentCredentialsErrors = { /** * Invalid request body or validation error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateAgentCredentialsError = UpdateAgentCredentialsErrors[keyof UpdateAgentCredentialsErrors]; export type UpdateAgentCredentialsResponses = { /** * Credentials updated successfully */ 204: void; }; export type UpdateAgentCredentialsResponse = UpdateAgentCredentialsResponses[keyof UpdateAgentCredentialsResponses]; export type ExecuteAgentData = { body: ExecuteAgentRequest; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/{id}/execute'; }; export type ExecuteAgentErrors = { /** * Invalid request body or agent is not active */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ExecuteAgentError = ExecuteAgentErrors[keyof ExecuteAgentErrors]; export type ExecuteAgentResponses = { /** * Execution created (streaming agents) or completed (non-streaming agents) */ 200: AgentExecution; }; export type ExecuteAgentResponse = ExecuteAgentResponses[keyof ExecuteAgentResponses]; export type ListAgentExecutionsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: { /** * Filter by execution status */ status?: string; /** * Filter executions started on or after this date */ date_from?: string; /** * Filter executions started on or before this date */ date_to?: string; /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/agents/{id}/executions'; }; export type ListAgentExecutionsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListAgentExecutionsError = ListAgentExecutionsErrors[keyof ListAgentExecutionsErrors]; export type ListAgentExecutionsResponses = { /** * Executions retrieved successfully */ 200: AgentExecutionListResponse; }; export type ListAgentExecutionsResponse = ListAgentExecutionsResponses[keyof ListAgentExecutionsResponses]; export type StartAgentExecutionData = { body: CreateAgentExecutionRequest; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/{id}/executions'; }; export type StartAgentExecutionErrors = { /** * Invalid request body */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type StartAgentExecutionError = StartAgentExecutionErrors[keyof StartAgentExecutionErrors]; export type StartAgentExecutionResponses = { /** * Execution started successfully */ 201: AgentExecution; }; export type StartAgentExecutionResponse = StartAgentExecutionResponses[keyof StartAgentExecutionResponses]; export type ListAgentConversationsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Agent identifier */ id: string; }; query?: { /** * Page number */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/agents/{id}/conversations'; }; export type ListAgentConversationsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Agent not found in the specified team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListAgentConversationsError = ListAgentConversationsErrors[keyof ListAgentConversationsErrors]; export type ListAgentConversationsResponses = { /** * Conversations retrieved successfully */ 200: ConversationListResponse; }; export type ListAgentConversationsResponse = ListAgentConversationsResponses[keyof ListAgentConversationsResponses]; export type GetAgentExecutionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Execution identifier */ execution_id: string; }; query?: never; url: '/api/v1/{team_id}/agents/executions/{execution_id}'; }; export type GetAgentExecutionErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Execution not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAgentExecutionError = GetAgentExecutionErrors[keyof GetAgentExecutionErrors]; export type GetAgentExecutionResponses = { /** * Execution retrieved successfully */ 200: AgentExecution; }; export type GetAgentExecutionResponse = GetAgentExecutionResponses[keyof GetAgentExecutionResponses]; export type CompleteAgentExecutionData = { body: UpdateAgentExecutionRequest; path: { /** * Team identifier */ team_id: string; /** * Execution identifier */ execution_id: string; }; query?: never; url: '/api/v1/{team_id}/agents/executions/{execution_id}'; }; export type CompleteAgentExecutionErrors = { /** * Invalid request body or status not one of running, success, error */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Execution not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CompleteAgentExecutionError = CompleteAgentExecutionErrors[keyof CompleteAgentExecutionErrors]; export type CompleteAgentExecutionResponses = { /** * Execution updated successfully */ 200: AgentExecution; }; export type CompleteAgentExecutionResponse = CompleteAgentExecutionResponses[keyof CompleteAgentExecutionResponses]; export type CancelAgentExecutionData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Execution identifier */ execution_id: string; }; query?: never; url: '/api/v1/{team_id}/agents/executions/{execution_id}/cancel'; }; export type CancelAgentExecutionErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Execution not found, or its agent does not belong to the specified team */ 404: ErrorResponse; /** * Execution is already terminal or its task cannot be cancelled */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CancelAgentExecutionError = CancelAgentExecutionErrors[keyof CancelAgentExecutionErrors]; export type CancelAgentExecutionResponses = { /** * Execution cancelled successfully */ 200: AgentExecution; }; export type CancelAgentExecutionResponse = CancelAgentExecutionResponses[keyof CancelAgentExecutionResponses]; export type GetAgentExecutionStatusData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Execution identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/agents/executions/{id}/status'; }; export type GetAgentExecutionStatusErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Execution not found, or its agent does not belong to the specified team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAgentExecutionStatusError = GetAgentExecutionStatusErrors[keyof GetAgentExecutionStatusErrors]; export type GetAgentExecutionStatusResponses = { /** * Execution status retrieved successfully */ 200: AgentExecution; }; export type GetAgentExecutionStatusResponse = GetAgentExecutionStatusResponses[keyof GetAgentExecutionStatusResponses]; export type GetAgentExecutionEventsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Execution identifier */ id: string; }; query?: { /** * Return events with a sequence number greater than this value (enables cursor-based polling) */ since?: number; /** * Page number (page-based mode only) */ page?: number; /** * Items per page (page-based mode only) */ limit?: number; }; url: '/api/v1/{team_id}/agents/executions/{id}/events'; }; export type GetAgentExecutionEventsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Execution not found, or its agent does not belong to the specified team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAgentExecutionEventsError = GetAgentExecutionEventsErrors[keyof GetAgentExecutionEventsErrors]; export type GetAgentExecutionEventsResponses = { /** * Events retrieved successfully (shape depends on whether `since` was provided) */ 200: AgentExecutionEventsResponse; }; export type GetAgentExecutionEventsResponse = GetAgentExecutionEventsResponses[keyof GetAgentExecutionEventsResponses]; export type ListConversationExecutionsData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Conversation identifier */ conversation_id: string; }; query?: { /** * Maximum number of executions to return */ limit?: number; /** * Return executions started before this RFC 3339 timestamp */ before?: string; }; url: '/api/v1/{team_id}/agents/conversations/{conversation_id}/executions'; }; export type ListConversationExecutionsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Conversation's agent does not belong to the specified team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListConversationExecutionsError = ListConversationExecutionsErrors[keyof ListConversationExecutionsErrors]; export type ListConversationExecutionsResponses = { /** * Conversation executions retrieved successfully */ 200: ConversationExecutionsResponse; }; export type ListConversationExecutionsResponse = ListConversationExecutionsResponses[keyof ListConversationExecutionsResponses]; export type ListTeamsData = { body?: never; path?: never; query?: { /** * Page number (1-based; defaults to 1) */ page?: number; /** * Items per page (defaults to 20, maximum 100) */ page_size?: number; }; url: '/api/v1/teams'; }; export type ListTeamsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListTeamsError = ListTeamsErrors[keyof ListTeamsErrors]; export type ListTeamsResponses = { /** * Teams retrieved successfully */ 200: TeamListResponse; }; export type ListTeamsResponse = ListTeamsResponses[keyof ListTeamsResponses]; export type CreateTeamData = { body: CreateTeamRequest; path?: never; query?: never; url: '/api/v1/teams'; }; export type CreateTeamErrors = { /** * Invalid request body or validation error (name required, name ≤ 100 chars, description ≤ 500 chars) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CreateTeamError = CreateTeamErrors[keyof CreateTeamErrors]; export type CreateTeamResponses = { /** * Team created successfully */ 201: Team; }; export type CreateTeamResponse = CreateTeamResponses[keyof CreateTeamResponses]; export type DeleteTeamData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}'; }; export type DeleteTeamErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not the team owner, personal workspace (code `CANNOT_DELETE_PERSONAL_WORKSPACE`), or default team */ 403: ErrorResponse; /** * Team not found */ 404: ErrorResponse; /** * Deletion blocked — the team still has members (code `TEAM_HAS_MEMBERS`) */ 409: TeamDeleteConflictError; /** * Internal server error */ 500: ErrorResponse; }; export type DeleteTeamError = DeleteTeamErrors[keyof DeleteTeamErrors]; export type DeleteTeamResponses = { /** * Team deleted successfully */ 204: void; }; export type DeleteTeamResponse = DeleteTeamResponses[keyof DeleteTeamResponses]; export type GetTeamData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}'; }; export type GetTeamErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Team not found (or the user has no access to it) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetTeamError = GetTeamErrors[keyof GetTeamErrors]; export type GetTeamResponses = { /** * Team retrieved successfully */ 200: Team; }; export type GetTeamResponse = GetTeamResponses[keyof GetTeamResponses]; export type UpdateTeamData = { body: UpdateTeamRequest; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}'; }; export type UpdateTeamErrors = { /** * Invalid request body or validation error (no fields provided, empty name, name ≤ 100 chars, description ≤ 500 chars) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — only team owners can update a team */ 403: ErrorResponse; /** * Team not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateTeamError = UpdateTeamErrors[keyof UpdateTeamErrors]; export type UpdateTeamResponses = { /** * Team updated successfully */ 200: Team; }; export type UpdateTeamResponse = UpdateTeamResponses[keyof UpdateTeamResponses]; export type GetTeamMembersData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: { /** * Page number (1-based; defaults to 1) */ page?: number; /** * Items per page (defaults to 100, maximum 100) */ page_size?: number; }; url: '/api/v1/teams/{id}/members'; }; export type GetTeamMembersErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Team not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetTeamMembersError = GetTeamMembersErrors[keyof GetTeamMembersErrors]; export type GetTeamMembersResponses = { /** * Team members retrieved successfully */ 200: TeamMembersListResponse; }; export type GetTeamMembersResponse = GetTeamMembersResponses[keyof GetTeamMembersResponses]; export type RemoveTeamMemberData = { body?: never; path: { /** * Team identifier */ id: string; /** * User ID of the member to remove */ userId: string; }; query?: never; url: '/api/v1/teams/{id}/members/{userId}'; }; export type RemoveTeamMemberErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — only team owners can remove members, or attempted to remove the team owner */ 403: ErrorResponse; /** * Team or member not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type RemoveTeamMemberError = RemoveTeamMemberErrors[keyof RemoveTeamMemberErrors]; export type RemoveTeamMemberResponses = { /** * Member removed successfully */ 204: void; }; export type RemoveTeamMemberResponse = RemoveTeamMemberResponses[keyof RemoveTeamMemberResponses]; export type UpdateTeamMemberRoleData = { body: UpdateTeamMemberRoleRequest; path: { /** * Team identifier */ id: string; /** * User ID of the member whose role is changing */ userId: string; }; query?: never; url: '/api/v1/teams/{id}/members/{userId}/role'; }; export type UpdateTeamMemberRoleErrors = { /** * Invalid request body or role value */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — caller is not an owner or admin of the team, or the target is the team owner */ 403: ErrorResponse; /** * Team not found, or the target user is not a member of the team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateTeamMemberRoleError = UpdateTeamMemberRoleErrors[keyof UpdateTeamMemberRoleErrors]; export type UpdateTeamMemberRoleResponses = { /** * Role updated successfully */ 200: UpdateTeamMemberRoleResponse; }; export type UpdateTeamMemberRoleResponse2 = UpdateTeamMemberRoleResponses[keyof UpdateTeamMemberRoleResponses]; export type TransferTeamOwnershipData = { body: TransferTeamOwnershipRequest; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}/transfer-ownership'; }; export type TransferTeamOwnershipErrors = { /** * Invalid request body, or the caller is already the target owner */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — caller is not the team owner, or the team is a personal workspace */ 403: ErrorResponse; /** * Team not found, or the target user is not a member of the team */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type TransferTeamOwnershipError = TransferTeamOwnershipErrors[keyof TransferTeamOwnershipErrors]; export type TransferTeamOwnershipResponses = { /** * Ownership transferred successfully */ 200: TransferTeamOwnershipResponse; }; export type TransferTeamOwnershipResponse2 = TransferTeamOwnershipResponses[keyof TransferTeamOwnershipResponses]; export type ListTeamInvitationsData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}/invitations'; }; export type ListTeamInvitationsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — no permission to view this team's invitations */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListTeamInvitationsError = ListTeamInvitationsErrors[keyof ListTeamInvitationsErrors]; export type ListTeamInvitationsResponses = { /** * Invitations retrieved successfully */ 200: InvitationResponseList; }; export type ListTeamInvitationsResponse = ListTeamInvitationsResponses[keyof ListTeamInvitationsResponses]; export type SendTeamInvitationsData = { body: SendInvitationsRequest; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}/invitations'; }; export type SendTeamInvitationsErrors = { /** * Invalid request body, validation error, more than 50 emails, or invalid role */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — personal workspace (code `upgrade_required`) or no permission to invite (code `FORBIDDEN`) */ 403: ErrorResponse; /** * Team not found */ 404: ErrorResponse; /** * Some invitees are already team members (code `DUPLICATE_MEMBERS`, includes `duplicate_emails` array) */ 409: InvitationDuplicateMembersError; /** * Internal server error */ 500: ErrorResponse; }; export type SendTeamInvitationsError = SendTeamInvitationsErrors[keyof SendTeamInvitationsErrors]; export type SendTeamInvitationsResponses = { /** * Invitations created successfully (the `token`, `team_name` and `invited_by` fields are not populated on this response) */ 201: InvitationResponseList; }; export type SendTeamInvitationsResponse = SendTeamInvitationsResponses[keyof SendTeamInvitationsResponses]; export type RevokeTeamInvitationData = { body?: never; path: { /** * Team identifier */ id: string; /** * Invitation identifier */ invitationId: string; }; query?: never; url: '/api/v1/teams/{id}/invitations/{invitationId}'; }; export type RevokeTeamInvitationErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — no permission to revoke invitations */ 403: ErrorResponse; /** * Invitation not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type RevokeTeamInvitationError = RevokeTeamInvitationErrors[keyof RevokeTeamInvitationErrors]; export type RevokeTeamInvitationResponses = { /** * Invitation revoked successfully */ 204: void; }; export type RevokeTeamInvitationResponse = RevokeTeamInvitationResponses[keyof RevokeTeamInvitationResponses]; export type GetTeamStatsData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: never; url: '/api/v1/teams/{id}/stats'; }; export type GetTeamStatsErrors = { /** * Invalid team id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type GetTeamStatsError = GetTeamStatsErrors[keyof GetTeamStatsErrors]; export type GetTeamStatsResponses = { /** * Team statistics retrieved successfully */ 200: TeamStatsResponse; }; export type GetTeamStatsResponse = GetTeamStatsResponses[keyof GetTeamStatsResponses]; export type GetTeamResourceCreationMetricsData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: { /** * The reporting window. Defaults to 30d. */ range?: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; }; url: '/api/v1/teams/{id}/resource-creation-metrics'; }; export type GetTeamResourceCreationMetricsErrors = { /** * Invalid request parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type GetTeamResourceCreationMetricsError = GetTeamResourceCreationMetricsErrors[keyof GetTeamResourceCreationMetricsErrors]; export type GetTeamResourceCreationMetricsResponses = { /** * Team resource creation metrics retrieved successfully */ 200: TeamResourceCreationMetricsResponse; }; export type GetTeamResourceCreationMetricsResponse = GetTeamResourceCreationMetricsResponses[keyof GetTeamResourceCreationMetricsResponses]; export type GetTeamResourceAccessMetricsData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: { /** * The reporting window. Defaults to 30d. */ range?: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; }; url: '/api/v1/teams/{id}/resource-access-metrics'; }; export type GetTeamResourceAccessMetricsErrors = { /** * Invalid request parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type GetTeamResourceAccessMetricsError = GetTeamResourceAccessMetricsErrors[keyof GetTeamResourceAccessMetricsErrors]; export type GetTeamResourceAccessMetricsResponses = { /** * Team resource access metrics retrieved successfully */ 200: ResourceAccessMetricsResponse; }; export type GetTeamResourceAccessMetricsResponse = GetTeamResourceAccessMetricsResponses[keyof GetTeamResourceAccessMetricsResponses]; export type GetTeamFeedCreationMetricsData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: { /** * The reporting window. Defaults to 30d. */ range?: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; }; url: '/api/v1/teams/{id}/feed-creation-metrics'; }; export type GetTeamFeedCreationMetricsErrors = { /** * Invalid request parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type GetTeamFeedCreationMetricsError = GetTeamFeedCreationMetricsErrors[keyof GetTeamFeedCreationMetricsErrors]; export type GetTeamFeedCreationMetricsResponses = { /** * Team feed creation metrics retrieved successfully */ 200: TeamFeedCreationMetricsResponse; }; export type GetTeamFeedCreationMetricsResponse = GetTeamFeedCreationMetricsResponses[keyof GetTeamFeedCreationMetricsResponses]; export type GetTeamTopAccessedResourcesData = { body?: never; path: { /** * Team identifier */ id: string; }; query?: { /** * The reporting window. Defaults to 30d. */ range?: '7d' | '14d' | '30d' | '60d' | '90d' | '180d'; /** * Maximum number of resources to return (1–50). Defaults to 5. */ limit?: number; /** * Restrict the ranking to a single access channel. Omitted or 'all' aggregates across all channels (the default behavior). */ source?: 'all' | 'web' | 'cli' | 'mcp' | 'api'; }; url: '/api/v1/teams/{id}/top-accessed-resources'; }; export type GetTeamTopAccessedResourcesErrors = { /** * Invalid request parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; }; export type GetTeamTopAccessedResourcesError = GetTeamTopAccessedResourcesErrors[keyof GetTeamTopAccessedResourcesErrors]; export type GetTeamTopAccessedResourcesResponses = { /** * Team top accessed resources retrieved successfully */ 200: TeamTopAccessedResourcesResponse; }; export type GetTeamTopAccessedResourcesResponse = GetTeamTopAccessedResourcesResponses[keyof GetTeamTopAccessedResourcesResponses]; export type GetPendingInvitationsData = { body?: never; path?: never; query?: never; url: '/api/v1/invitations/pending'; }; export type GetPendingInvitationsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetPendingInvitationsError = GetPendingInvitationsErrors[keyof GetPendingInvitationsErrors]; export type GetPendingInvitationsResponses = { /** * Pending invitations retrieved successfully */ 200: PendingInvitationsListResponse; }; export type GetPendingInvitationsResponse = GetPendingInvitationsResponses[keyof GetPendingInvitationsResponses]; export type AcceptInvitationData = { body?: never; path: { /** * Opaque invitation token from the invitation email link */ token: string; }; query?: never; url: '/api/v1/invitations/{token}/accept'; }; export type AcceptInvitationErrors = { /** * Invitation is not pending */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Invitation was sent to a different email address */ 403: ErrorResponse; /** * Invalid invitation token */ 404: ErrorResponse; /** * Already a member of this team */ 409: ErrorResponse; /** * Invitation has expired */ 410: ErrorResponse; /** * Internal server error (including invitation accepted but team details could not be fetched) */ 500: ErrorResponse; }; export type AcceptInvitationError = AcceptInvitationErrors[keyof AcceptInvitationErrors]; export type AcceptInvitationResponses = { /** * Invitation accepted successfully */ 200: AcceptInvitationResponse; }; export type AcceptInvitationResponse2 = AcceptInvitationResponses[keyof AcceptInvitationResponses]; export type RejectInvitationData = { body?: never; path: { /** * Opaque invitation token from the invitation email link */ token: string; }; query?: never; url: '/api/v1/invitations/{token}/reject'; }; export type RejectInvitationErrors = { /** * Invitation is not pending */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Not authorized to reject this invitation */ 403: ErrorResponse; /** * Invalid invitation token */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type RejectInvitationError = RejectInvitationErrors[keyof RejectInvitationErrors]; export type RejectInvitationResponses = { /** * Invitation rejected successfully */ 204: void; }; export type RejectInvitationResponse = RejectInvitationResponses[keyof RejectInvitationResponses]; export type ListNotificationsData = { body?: never; path?: never; query?: { /** * Maximum number of notifications to return (1-100) */ limit?: number; /** * Number of notifications to skip */ offset?: number; /** * When true, return only unread notifications */ unread?: boolean; }; url: '/api/v1/notifications'; }; export type ListNotificationsErrors = { /** * Invalid query parameter (limit not in 1-100, negative offset, or non-boolean unread) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Failed to list notifications */ 500: ErrorResponse; }; export type ListNotificationsError = ListNotificationsErrors[keyof ListNotificationsErrors]; export type ListNotificationsResponses = { /** * Notifications retrieved successfully */ 200: NotificationListResponse; }; export type ListNotificationsResponse = ListNotificationsResponses[keyof ListNotificationsResponses]; export type GetUnreadNotificationCountData = { body?: never; path?: never; query?: never; url: '/api/v1/notifications/unread-count'; }; export type GetUnreadNotificationCountErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to get unread notification count */ 500: ErrorResponse; }; export type GetUnreadNotificationCountError = GetUnreadNotificationCountErrors[keyof GetUnreadNotificationCountErrors]; export type GetUnreadNotificationCountResponses = { /** * Unread count retrieved successfully */ 200: UnreadCountResponse; }; export type GetUnreadNotificationCountResponse = GetUnreadNotificationCountResponses[keyof GetUnreadNotificationCountResponses]; export type MarkNotificationReadData = { body?: never; path: { /** * Notification identifier */ id: string; }; query?: never; url: '/api/v1/notifications/{id}/read'; }; export type MarkNotificationReadErrors = { /** * Notification id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Failed to mark notification as read */ 500: ErrorResponse; }; export type MarkNotificationReadError = MarkNotificationReadErrors[keyof MarkNotificationReadErrors]; export type MarkNotificationReadResponses = { /** * Notification marked as read (no content) */ 204: void; }; export type MarkNotificationReadResponse = MarkNotificationReadResponses[keyof MarkNotificationReadResponses]; export type MarkAllNotificationsReadData = { body?: never; path?: never; query?: never; url: '/api/v1/notifications/read-all'; }; export type MarkAllNotificationsReadErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to mark all notifications as read */ 500: ErrorResponse; }; export type MarkAllNotificationsReadError = MarkAllNotificationsReadErrors[keyof MarkAllNotificationsReadErrors]; export type MarkAllNotificationsReadResponses = { /** * All notifications marked as read (no content) */ 204: void; }; export type MarkAllNotificationsReadResponse = MarkAllNotificationsReadResponses[keyof MarkAllNotificationsReadResponses]; export type ListTypesData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query: { /** * Resource whose types to list (currently only "artifacts") */ resource_type: string; }; url: '/api/v1/{team_id}/types'; }; export type ListTypesErrors = { /** * Missing or unsupported resource_type */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to list types */ 500: ErrorResponse; }; export type ListTypesError = ListTypesErrors[keyof ListTypesErrors]; export type ListTypesResponses = { /** * Types retrieved successfully */ 200: TypeListResponse; }; export type ListTypesResponse = ListTypesResponses[keyof ListTypesResponses]; export type CreateTypeData = { body: CreateTypeRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/types'; }; export type CreateTypeErrors = { /** * Invalid or unsupported resource_type, slug, or name */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * A type with the same slug already exists for this resource */ 409: ErrorResponse; /** * Failed to create type */ 500: ErrorResponse; }; export type CreateTypeError = CreateTypeErrors[keyof CreateTypeErrors]; export type CreateTypeResponses = { /** * Type created successfully */ 201: Type; }; export type CreateTypeResponse = CreateTypeResponses[keyof CreateTypeResponses]; export type DeleteTypeData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Type identifier */ id: string; }; query?: never; url: '/api/v1/{team_id}/types/{id}'; }; export type DeleteTypeErrors = { /** * Type id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * No deletable custom type with this id exists in the team */ 404: ErrorResponse; /** * Failed to delete type */ 500: ErrorResponse; }; export type DeleteTypeError = DeleteTypeErrors[keyof DeleteTypeErrors]; export type DeleteTypeResponses = { /** * Type deleted (no content) */ 204: void; }; export type DeleteTypeResponse = DeleteTypeResponses[keyof DeleteTypeResponses]; export type CopyTypesFromTeamData = { body: CopyTypesRequest; path: { /** * Destination team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/types/copy'; }; export type CopyTypesFromTeamErrors = { /** * Missing body, malformed source_team_id, or source equal to destination */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the destination team or of the source team. The two are deliberately indistinguishable, so the response never reveals whether the source team exists. * */ 403: ErrorResponse; /** * Failed to copy types */ 500: ErrorResponse; }; export type CopyTypesFromTeamError = CopyTypesFromTeamErrors[keyof CopyTypesFromTeamErrors]; export type CopyTypesFromTeamResponses = { /** * Copy completed (possibly with everything skipped) */ 200: CopyTypesResponse; }; export type CopyTypesFromTeamResponse = CopyTypesFromTeamResponses[keyof CopyTypesFromTeamResponses]; export type GetAdminStatsData = { body?: never; path?: never; query?: never; url: '/api/v1/admin/stats'; }; export type GetAdminStatsErrors = { /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAdminStatsError = GetAdminStatsErrors[keyof GetAdminStatsErrors]; export type GetAdminStatsResponses = { /** * Instance statistics retrieved successfully */ 200: AdminStatsResponse; }; export type GetAdminStatsResponse = GetAdminStatsResponses[keyof GetAdminStatsResponses]; export type ListAdminUsersData = { body?: never; path?: never; query?: { /** * 1-based page number */ page?: number; /** * Items per page */ limit?: number; /** * Case-insensitive substring match over the user's email and name. */ search?: string; /** * Exact match on the user's identity-provider name (e.g. "google", "oidc"). */ idp_provider?: string; /** * Only users created at or after this instant (inclusive). */ created_from?: string; /** * Only users created at or before this instant (inclusive). */ created_to?: string; /** * Narrow to accounts in this lifecycle state. */ status?: 'active' | 'suspended'; /** * Column to sort by. Ties are always broken by user id so paging is stable. */ sort_by?: 'created_at' | 'email' | 'name' | 'team_count'; /** * Sort direction. */ sort_order?: 'asc' | 'desc'; }; url: '/api/v1/admin/users'; }; export type ListAdminUsersErrors = { /** * Bad request — a query parameter is malformed or outside its enum */ 400: ErrorResponse; /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListAdminUsersError = ListAdminUsersErrors[keyof ListAdminUsersErrors]; export type ListAdminUsersResponses = { /** * A page of users */ 200: AdminUserListResponse; }; export type ListAdminUsersResponse = ListAdminUsersResponses[keyof ListAdminUsersResponses]; export type CreateAdminUserData = { body: AdminUserCreateRequest; path?: never; query?: never; url: '/api/v1/admin/users'; }; export type CreateAdminUserErrors = { /** * Bad request — missing or malformed email/name, or an unknown field */ 400: ErrorResponse; /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Conflict — a user with that email already exists; nothing was created */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CreateAdminUserError = CreateAdminUserErrors[keyof CreateAdminUserErrors]; export type CreateAdminUserResponses = { /** * The created user */ 201: AdminUserDetail; }; export type CreateAdminUserResponse = CreateAdminUserResponses[keyof CreateAdminUserResponses]; export type DeleteAdminUserData = { body?: never; path: { /** * User id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/users/{id}'; }; export type DeleteAdminUserErrors = { /** * Bad request — malformed user id */ 400: ErrorResponse; /** * Not found — unknown user id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Conflict — the delete was refused and NOTHING was deleted. Either the * user owns shared teams with other members (see `blockers`), or the * target is the acting admin or a config-listed instance admin. * */ 409: AdminUserDeleteBlockedResponse; /** * Internal server error */ 500: ErrorResponse; }; export type DeleteAdminUserError = DeleteAdminUserErrors[keyof DeleteAdminUserErrors]; export type DeleteAdminUserResponses = { /** * The user was deleted */ 204: void; }; export type DeleteAdminUserResponse = DeleteAdminUserResponses[keyof DeleteAdminUserResponses]; export type GetAdminUserData = { body?: never; path: { /** * User id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/users/{id}'; }; export type GetAdminUserErrors = { /** * Not found — unknown user id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAdminUserError = GetAdminUserErrors[keyof GetAdminUserErrors]; export type GetAdminUserResponses = { /** * The user with their team memberships */ 200: AdminUserDetail; }; export type GetAdminUserResponse = GetAdminUserResponses[keyof GetAdminUserResponses]; export type UpdateAdminUserData = { body: AdminUserUpdateRequest; path: { /** * User id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/users/{id}'; }; export type UpdateAdminUserErrors = { /** * Bad request — malformed id, or a body carrying an unknown or non-editable field */ 400: ErrorResponse; /** * Not found — unknown user id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateAdminUserError = UpdateAdminUserErrors[keyof UpdateAdminUserErrors]; export type UpdateAdminUserResponses = { /** * The updated user */ 200: AdminUserDetail; }; export type UpdateAdminUserResponse = UpdateAdminUserResponses[keyof UpdateAdminUserResponses]; export type ListAdminTeamsData = { body?: never; path?: never; query?: { /** * 1-based page number */ page?: number; /** * Items per page */ limit?: number; /** * Case-insensitive substring match over the team name, team slug, and the owner's email. */ search?: string; /** * Narrow to personal workspaces (true) or shared team workspaces (false). */ is_personal?: boolean; /** * Only teams created at or after this instant (inclusive). */ created_from?: string; /** * Only teams created at or before this instant (inclusive). */ created_to?: string; /** * Column to sort by. Ties are always broken by team id so paging is stable. */ sort_by?: 'created_at' | 'name' | 'member_count'; /** * Sort direction. */ sort_order?: 'asc' | 'desc'; }; url: '/api/v1/admin/teams'; }; export type ListAdminTeamsErrors = { /** * Bad request — a query parameter is malformed or outside its enum */ 400: ErrorResponse; /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListAdminTeamsError = ListAdminTeamsErrors[keyof ListAdminTeamsErrors]; export type ListAdminTeamsResponses = { /** * A page of teams */ 200: AdminTeamListResponse; }; export type ListAdminTeamsResponse = ListAdminTeamsResponses[keyof ListAdminTeamsResponses]; export type GetAdminTeamData = { body?: never; path: { /** * Team id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/teams/{id}'; }; export type GetAdminTeamErrors = { /** * Not found — unknown team id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAdminTeamError = GetAdminTeamErrors[keyof GetAdminTeamErrors]; export type GetAdminTeamResponses = { /** * The team with its owner and members */ 200: AdminTeamDetail; }; export type GetAdminTeamResponse = GetAdminTeamResponses[keyof GetAdminTeamResponses]; export type GetAdminDashboardOverviewData = { body?: never; path?: never; query?: never; url: '/api/v1/admin/dashboard/overview'; }; export type GetAdminDashboardOverviewErrors = { /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAdminDashboardOverviewError = GetAdminDashboardOverviewErrors[keyof GetAdminDashboardOverviewErrors]; export type GetAdminDashboardOverviewResponses = { /** * Dashboard overview */ 200: AdminDashboardOverview; }; export type GetAdminDashboardOverviewResponse = GetAdminDashboardOverviewResponses[keyof GetAdminDashboardOverviewResponses]; export type GetAdminDashboardTimeseriesData = { body?: never; path?: never; query?: { /** * Inclusive start of the range. Defaults to 30 days before `to`. */ from?: string; /** * Exclusive end of the range. Defaults to now. */ to?: string; /** * Bucket size. */ granularity?: 'day' | 'week' | 'month'; }; url: '/api/v1/admin/dashboard/timeseries'; }; export type GetAdminDashboardTimeseriesErrors = { /** * Bad request — `to` is not after `from`, the range exceeds the maximum * span, or `granularity` is outside its enum * */ 400: ErrorResponse; /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAdminDashboardTimeseriesError = GetAdminDashboardTimeseriesErrors[keyof GetAdminDashboardTimeseriesErrors]; export type GetAdminDashboardTimeseriesResponses = { /** * Bucketed time series for the requested range */ 200: AdminTimeseriesResponse; }; export type GetAdminDashboardTimeseriesResponse = GetAdminDashboardTimeseriesResponses[keyof GetAdminDashboardTimeseriesResponses]; export type SuspendAdminUserData = { body?: never; path: { /** * User id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/users/{id}/suspend'; }; export type SuspendAdminUserErrors = { /** * Bad request — malformed user id */ 400: ErrorResponse; /** * Not found — unknown user id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Conflict — the acting admin cannot suspend themselves or a config-listed instance admin */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type SuspendAdminUserError = SuspendAdminUserErrors[keyof SuspendAdminUserErrors]; export type SuspendAdminUserResponses = { /** * The updated user */ 200: AdminUserDetail; }; export type SuspendAdminUserResponse = SuspendAdminUserResponses[keyof SuspendAdminUserResponses]; export type ReactivateAdminUserData = { body?: never; path: { /** * User id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/users/{id}/reactivate'; }; export type ReactivateAdminUserErrors = { /** * Bad request — malformed user id */ 400: ErrorResponse; /** * Not found — unknown user id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ReactivateAdminUserError = ReactivateAdminUserErrors[keyof ReactivateAdminUserErrors]; export type ReactivateAdminUserResponses = { /** * The updated user */ 200: AdminUserDetail; }; export type ReactivateAdminUserResponse = ReactivateAdminUserResponses[keyof ReactivateAdminUserResponses]; export type ListAdminProjectsData = { body?: never; path?: never; query?: { /** * 1-based page number */ page?: number; /** * Items per page */ limit?: number; /** * Case-insensitive substring match over the project name and slug. */ search?: string; /** * Narrow to projects belonging to one team. */ team_id?: string; /** * Only projects created at or after this instant (inclusive). */ created_from?: string; /** * Only projects created at or before this instant (inclusive). */ created_to?: string; /** * Column to sort by. Ties are always broken by project id so paging is stable. */ sort_by?: 'created_at' | 'name'; /** * Sort direction. */ sort_order?: 'asc' | 'desc'; }; url: '/api/v1/admin/projects'; }; export type ListAdminProjectsErrors = { /** * Bad request — a query parameter is malformed or outside its enum */ 400: ErrorResponse; /** * Not found — the caller is not an instance admin (surface not advertised) */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListAdminProjectsError = ListAdminProjectsErrors[keyof ListAdminProjectsErrors]; export type ListAdminProjectsResponses = { /** * A page of projects */ 200: AdminProjectListResponse; }; export type ListAdminProjectsResponse = ListAdminProjectsResponses[keyof ListAdminProjectsResponses]; export type GetAdminProjectData = { body?: never; path: { /** * Project id (UUID) */ id: string; }; query?: never; url: '/api/v1/admin/projects/{id}'; }; export type GetAdminProjectErrors = { /** * Bad request — malformed project id */ 400: ErrorResponse; /** * Not found — unknown project id, or the caller is not an instance admin */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetAdminProjectError = GetAdminProjectErrors[keyof GetAdminProjectErrors]; export type GetAdminProjectResponses = { /** * The project with its team, owner and resource counts */ 200: AdminProjectDetail; }; export type GetAdminProjectResponse = GetAdminProjectResponses[keyof GetAdminProjectResponses]; export type ListCommentsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query: { /** * Type of the commented resource (artifact, memory, prompt, or blueprint) */ resource_type: string; /** * Identifier of the commented resource */ resource_id: string; /** * Page number (1-based) */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/comments'; }; export type ListCommentsErrors = { /** * Invalid resource_type or query parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to list comments */ 500: ErrorResponse; }; export type ListCommentsError = ListCommentsErrors[keyof ListCommentsErrors]; export type ListCommentsResponses = { /** * Comments retrieved successfully */ 200: CommentListResponse; }; export type ListCommentsResponse = ListCommentsResponses[keyof ListCommentsResponses]; export type CreateCommentData = { body: CreateCommentRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/comments'; }; export type CreateCommentErrors = { /** * Invalid resource_type or content */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller may not comment in the team */ 403: ErrorResponse; /** * Target resource not found in the team */ 404: ErrorResponse; /** * Failed to create comment */ 500: ErrorResponse; }; export type CreateCommentError = CreateCommentErrors[keyof CreateCommentErrors]; export type CreateCommentResponses = { /** * Comment created successfully */ 201: Comment; }; export type CreateCommentResponse = CreateCommentResponses[keyof CreateCommentResponses]; export type ListRecentCommentsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Maximum number of entries to return */ limit?: number; }; url: '/api/v1/{team_id}/comments/recent'; }; export type ListRecentCommentsErrors = { /** * Invalid query parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to list recent comments */ 500: ErrorResponse; }; export type ListRecentCommentsError = ListRecentCommentsErrors[keyof ListRecentCommentsErrors]; export type ListRecentCommentsResponses = { /** * Recent comments retrieved successfully */ 200: RecentCommentListResponse; }; export type ListRecentCommentsResponse = ListRecentCommentsResponses[keyof ListRecentCommentsResponses]; export type DeleteCommentData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Comment identifier */ comment_id: string; }; query?: never; url: '/api/v1/{team_id}/comments/{comment_id}'; }; export type DeleteCommentErrors = { /** * comment_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller may not delete this comment */ 403: ErrorResponse; /** * Comment not found in the team */ 404: ErrorResponse; /** * Failed to delete comment */ 500: ErrorResponse; }; export type DeleteCommentError = DeleteCommentErrors[keyof DeleteCommentErrors]; export type DeleteCommentResponses = { /** * Comment deleted (no content) */ 204: void; }; export type DeleteCommentResponse = DeleteCommentResponses[keyof DeleteCommentResponses]; export type UpdateCommentData = { body: UpdateCommentRequest; path: { /** * Team identifier */ team_id: string; /** * Comment identifier */ comment_id: string; }; query?: never; url: '/api/v1/{team_id}/comments/{comment_id}'; }; export type UpdateCommentErrors = { /** * Invalid content */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not the comment's author */ 403: ErrorResponse; /** * Comment not found in the team */ 404: ErrorResponse; /** * Failed to update comment */ 500: ErrorResponse; }; export type UpdateCommentError = UpdateCommentErrors[keyof UpdateCommentErrors]; export type UpdateCommentResponses = { /** * Comment updated successfully */ 200: Comment; }; export type UpdateCommentResponse = UpdateCommentResponses[keyof UpdateCommentResponses]; export type ListRelationsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query: { /** * Type of the resource whose relations to list (artifact, memory, prompt, or blueprint) */ resource_type: string; /** * Identifier of the resource whose relations to list */ resource_id: string; /** * Page number (1-based) */ page?: number; /** * Items per page */ limit?: number; }; url: '/api/v1/{team_id}/relations'; }; export type ListRelationsErrors = { /** * Invalid resource_type or query parameters */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to list relations */ 500: ErrorResponse; }; export type ListRelationsError = ListRelationsErrors[keyof ListRelationsErrors]; export type ListRelationsResponses = { /** * Relations retrieved successfully */ 200: RelationListResponse; }; export type ListRelationsResponse = ListRelationsResponses[keyof ListRelationsResponses]; export type CreateRelationData = { body: CreateRelationRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/relations'; }; export type CreateRelationErrors = { /** * Invalid types, self-link, cross-project link, or matrix violation */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller may not create relations in the team */ 403: ErrorResponse; /** * One of the endpoints does not exist in the team */ 404: ErrorResponse; /** * Failed to create relation */ 500: ErrorResponse; }; export type CreateRelationError = CreateRelationErrors[keyof CreateRelationErrors]; export type CreateRelationResponses = { /** * Relation already existed; the existing edge is returned (idempotent create) */ 200: Relation; /** * Relation created successfully */ 201: Relation; }; export type CreateRelationResponse = CreateRelationResponses[keyof CreateRelationResponses]; export type ConfirmRelationData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Relation identifier */ relation_id: string; }; query?: never; url: '/api/v1/{team_id}/relations/{relation_id}/confirm'; }; export type ConfirmRelationErrors = { /** * relation_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller may not confirm relations in the team */ 403: ErrorResponse; /** * Relation not found in the team */ 404: ErrorResponse; /** * Relation is already confirmed */ 409: ErrorResponse; /** * Failed to confirm relation */ 500: ErrorResponse; }; export type ConfirmRelationError = ConfirmRelationErrors[keyof ConfirmRelationErrors]; export type ConfirmRelationResponses = { /** * Relation confirmed successfully */ 200: Relation; }; export type ConfirmRelationResponse = ConfirmRelationResponses[keyof ConfirmRelationResponses]; export type DeleteRelationData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Relation identifier */ relation_id: string; }; query?: never; url: '/api/v1/{team_id}/relations/{relation_id}'; }; export type DeleteRelationErrors = { /** * relation_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller may not delete this relation */ 403: ErrorResponse; /** * Relation not found in the team */ 404: ErrorResponse; /** * Failed to delete relation */ 500: ErrorResponse; }; export type DeleteRelationError = DeleteRelationErrors[keyof DeleteRelationErrors]; export type DeleteRelationResponses = { /** * Relation deleted (no content) */ 204: void; }; export type DeleteRelationResponse = DeleteRelationResponses[keyof DeleteRelationResponses]; export type SeedRelationsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/relations/seed'; }; export type SeedRelationsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Caller may not create relations in the team */ 403: ErrorResponse; /** * Failed to trigger the relation seed backfill */ 500: ErrorResponse; }; export type SeedRelationsError = SeedRelationsErrors[keyof SeedRelationsErrors]; export type SeedRelationsResponses = { /** * Seed backfill accepted and running in the background (no content) */ 202: unknown; }; export type ListEmbeddingProvidersData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers'; }; export type ListEmbeddingProvidersErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to retrieve embedding providers (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ListEmbeddingProvidersError = ListEmbeddingProvidersErrors[keyof ListEmbeddingProvidersErrors]; export type ListEmbeddingProvidersResponses = { /** * Embedding providers retrieved successfully */ 200: EmbeddingProviderArrayResponse; }; export type ListEmbeddingProvidersResponse = ListEmbeddingProvidersResponses[keyof ListEmbeddingProvidersResponses]; export type CreateEmbeddingProviderData = { body: CreateEmbeddingProviderRequest; path: { /** * Team that owns the embedding provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers'; }; export type CreateEmbeddingProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * A provider with the same name already exists (`PROVIDER_ALREADY_EXISTS`) */ 409: ErrorResponse; /** * Provider creation failed (`PROVIDER_CREATE_FAILED`) */ 500: ErrorResponse; }; export type CreateEmbeddingProviderError = CreateEmbeddingProviderErrors[keyof CreateEmbeddingProviderErrors]; export type CreateEmbeddingProviderResponses = { /** * Embedding provider created successfully */ 200: EmbeddingProviderResponse; }; export type CreateEmbeddingProviderResponse = CreateEmbeddingProviderResponses[keyof CreateEmbeddingProviderResponses]; export type GetEmbeddingCoverageData = { body?: never; path: { /** * Team whose embedding coverage is reported. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers/coverage'; }; export type GetEmbeddingCoverageErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to retrieve embedding coverage (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type GetEmbeddingCoverageError = GetEmbeddingCoverageErrors[keyof GetEmbeddingCoverageErrors]; export type GetEmbeddingCoverageResponses = { /** * Embedding coverage retrieved successfully */ 200: EmbeddingCoverageResponse; }; export type GetEmbeddingCoverageResponse = GetEmbeddingCoverageResponses[keyof GetEmbeddingCoverageResponses]; export type DeleteEmbeddingProviderData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers/{id}'; }; export type DeleteEmbeddingProviderErrors = { /** * Cannot delete the last embedding provider (`PROVIDER_LAST_DELETE_BLOCKED`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider deletion failed (`PROVIDER_DELETE_FAILED`) */ 500: ErrorResponse; }; export type DeleteEmbeddingProviderError = DeleteEmbeddingProviderErrors[keyof DeleteEmbeddingProviderErrors]; export type DeleteEmbeddingProviderResponses = { /** * Embedding provider deleted successfully (no body) */ 204: void; }; export type DeleteEmbeddingProviderResponse = DeleteEmbeddingProviderResponses[keyof DeleteEmbeddingProviderResponses]; export type GetEmbeddingProviderData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers/{id}'; }; export type GetEmbeddingProviderErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Failed to retrieve embedding provider (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type GetEmbeddingProviderError = GetEmbeddingProviderErrors[keyof GetEmbeddingProviderErrors]; export type GetEmbeddingProviderResponses = { /** * Embedding provider retrieved successfully */ 200: EmbeddingProviderResponse; }; export type GetEmbeddingProviderResponse = GetEmbeddingProviderResponses[keyof GetEmbeddingProviderResponses]; export type UpdateEmbeddingProviderData = { body: UpdateEmbeddingProviderRequest; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers/{id}'; }; export type UpdateEmbeddingProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider update failed (`PROVIDER_UPDATE_FAILED`) */ 500: ErrorResponse; }; export type UpdateEmbeddingProviderError = UpdateEmbeddingProviderErrors[keyof UpdateEmbeddingProviderErrors]; export type UpdateEmbeddingProviderResponses = { /** * Embedding provider updated successfully */ 200: EmbeddingProviderResponse; }; export type UpdateEmbeddingProviderResponse = UpdateEmbeddingProviderResponses[keyof UpdateEmbeddingProviderResponses]; export type ReprocessEmbeddingProviderData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers/{id}/reprocess'; }; export type ReprocessEmbeddingProviderErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Failed to load the provider before reprocess (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ReprocessEmbeddingProviderError = ReprocessEmbeddingProviderErrors[keyof ReprocessEmbeddingProviderErrors]; export type ReprocessEmbeddingProviderResponses = { /** * Reprocess accepted; embeddings are regenerated in the background. */ 202: SuccessResponse; }; export type ReprocessEmbeddingProviderResponse = ReprocessEmbeddingProviderResponses[keyof ReprocessEmbeddingProviderResponses]; export type ValidateEmbeddingProviderData = { body: ValidateEmbeddingProviderRequest; path: { /** * Team that owns the embedding provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/embedding-providers/validate'; }; export type ValidateEmbeddingProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Validation failed due to an internal service error (`INTERNAL_ERROR`) */ 500: ErrorResponse; }; export type ValidateEmbeddingProviderError = ValidateEmbeddingProviderErrors[keyof ValidateEmbeddingProviderErrors]; export type ValidateEmbeddingProviderResponses = { /** * Validation completed (check `is_valid` for the outcome) */ 200: ValidateEmbeddingProviderResponse; }; export type ValidateEmbeddingProviderResponse2 = ValidateEmbeddingProviderResponses[keyof ValidateEmbeddingProviderResponses]; export type GetMetadataKeysData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query: { /** * Which resource type's metadata to enumerate */ resource_type: 'artifacts' | 'blueprints' | 'memories'; /** * Narrow the catalog to a single project */ project_id?: string; /** * Maximum number of keys to return */ limit?: number; }; url: '/api/v1/{team_id}/metadata/keys'; }; export type GetMetadataKeysErrors = { /** * Invalid or missing query parameter */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetMetadataKeysError = GetMetadataKeysErrors[keyof GetMetadataKeysErrors]; export type GetMetadataKeysResponses = { /** * Metadata keys retrieved successfully */ 200: MetadataKeysResponse; }; export type GetMetadataKeysResponse = GetMetadataKeysResponses[keyof GetMetadataKeysResponses]; export type GetMetadataValuesData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query: { /** * Which resource type's metadata to enumerate */ resource_type: 'artifacts' | 'blueprints' | 'memories'; /** * The metadata key whose values to enumerate */ key: string; /** * Narrow the catalog to a single project */ project_id?: string; /** * Case-insensitive substring filter for typeahead */ q?: string; /** * Maximum number of values to return */ limit?: number; }; url: '/api/v1/{team_id}/metadata/values'; }; export type GetMetadataValuesErrors = { /** * Invalid or missing query parameter */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetMetadataValuesError = GetMetadataValuesErrors[keyof GetMetadataValuesErrors]; export type GetMetadataValuesResponses = { /** * Metadata values retrieved successfully */ 200: MetadataValuesResponse; }; export type GetMetadataValuesResponse = GetMetadataValuesResponses[keyof GetMetadataValuesResponses]; export type ResetTeamSearchSettingsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/search'; }; export type ResetTeamSearchSettingsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller's role does not grant team.settings.update */ 403: ErrorResponse; /** * Failed to reset the team's search settings */ 500: ErrorResponse; }; export type ResetTeamSearchSettingsError = ResetTeamSearchSettingsErrors[keyof ResetTeamSearchSettingsErrors]; export type ResetTeamSearchSettingsResponses = { /** * Settings reset (no content); the team now inherits the instance defaults */ 204: void; }; export type ResetTeamSearchSettingsResponse = ResetTeamSearchSettingsResponses[keyof ResetTeamSearchSettingsResponses]; export type GetTeamSearchSettingsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/search'; }; export type GetTeamSearchSettingsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to read the team's search settings */ 500: ErrorResponse; }; export type GetTeamSearchSettingsError = GetTeamSearchSettingsErrors[keyof GetTeamSearchSettingsErrors]; export type GetTeamSearchSettingsResponses = { /** * Settings retrieved successfully */ 200: TeamSearchSettings; }; export type GetTeamSearchSettingsResponse = GetTeamSearchSettingsResponses[keyof GetTeamSearchSettingsResponses]; export type UpdateTeamSearchSettingsData = { body: UpdateTeamSearchSettingsRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/search'; }; export type UpdateTeamSearchSettingsErrors = { /** * Invalid ranking parameters — a negative weight, all weights zero, or a half-life outside (0, 36500] * */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller's role does not grant team.settings.update */ 403: ErrorResponse; /** * Failed to store the team's search settings */ 500: ErrorResponse; }; export type UpdateTeamSearchSettingsError = UpdateTeamSearchSettingsErrors[keyof UpdateTeamSearchSettingsErrors]; export type UpdateTeamSearchSettingsResponses = { /** * Settings stored successfully; the response reports source `team` */ 200: TeamSearchSettings; }; export type UpdateTeamSearchSettingsResponse = UpdateTeamSearchSettingsResponses[keyof UpdateTeamSearchSettingsResponses]; export type ListTeamSettingsAuditData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Page number (1-based). The upper bound is not a storage limit — it keeps page * limit inside the range the offset arithmetic can represent, so an absurd page is rejected rather than silently wrapping around to the first one. * */ page?: number; /** * Entries per page */ limit?: number; }; url: '/api/v1/{team_id}/settings/audit'; }; export type ListTeamSettingsAuditErrors = { /** * Invalid team_id or query parameter */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller's role does not grant team.settings.update */ 403: ErrorResponse; /** * Failed to list the team's settings audit log */ 500: ErrorResponse; }; export type ListTeamSettingsAuditError = ListTeamSettingsAuditErrors[keyof ListTeamSettingsAuditErrors]; export type ListTeamSettingsAuditResponses = { /** * Audit log retrieved successfully */ 200: TeamSettingsAuditListResponse; }; export type ListTeamSettingsAuditResponse = ListTeamSettingsAuditResponses[keyof ListTeamSettingsAuditResponses]; export type ListFreshnessRulesData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/rules'; }; export type ListFreshnessRulesErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to list the team's freshness rules */ 500: ErrorResponse; }; export type ListFreshnessRulesError = ListFreshnessRulesErrors[keyof ListFreshnessRulesErrors]; export type ListFreshnessRulesResponses = { /** * Rules retrieved successfully */ 200: FreshnessRuleListResponse; }; export type ListFreshnessRulesResponse = ListFreshnessRulesResponses[keyof ListFreshnessRulesResponses]; export type CreateFreshnessRuleData = { body: CreateFreshnessRuleRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/rules'; }; export type CreateFreshnessRuleErrors = { /** * Invalid team_id or rule definition */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller may not change the team's settings */ 403: ErrorResponse; /** * Failed to create the freshness rule */ 500: ErrorResponse; }; export type CreateFreshnessRuleError = CreateFreshnessRuleErrors[keyof CreateFreshnessRuleErrors]; export type CreateFreshnessRuleResponses = { /** * Rule created successfully */ 201: FreshnessRule; }; export type CreateFreshnessRuleResponse = CreateFreshnessRuleResponses[keyof CreateFreshnessRuleResponses]; export type DeleteFreshnessRuleData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Freshness rule identifier */ rule_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/rules/{rule_id}'; }; export type DeleteFreshnessRuleErrors = { /** * Invalid identifiers */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller may not change the team's settings */ 403: ErrorResponse; /** * No such rule in this team */ 404: ErrorResponse; /** * Failed to delete the freshness rule */ 500: ErrorResponse; }; export type DeleteFreshnessRuleError = DeleteFreshnessRuleErrors[keyof DeleteFreshnessRuleErrors]; export type DeleteFreshnessRuleResponses = { /** * Rule deleted (no content) */ 204: void; }; export type DeleteFreshnessRuleResponse = DeleteFreshnessRuleResponses[keyof DeleteFreshnessRuleResponses]; export type UpdateFreshnessRuleData = { body: UpdateFreshnessRuleRequest; path: { /** * Team identifier */ team_id: string; /** * Freshness rule identifier */ rule_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/rules/{rule_id}'; }; export type UpdateFreshnessRuleErrors = { /** * Invalid identifiers or rule definition */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller may not change the team's settings */ 403: ErrorResponse; /** * No such rule in this team */ 404: ErrorResponse; /** * Failed to update the freshness rule */ 500: ErrorResponse; }; export type UpdateFreshnessRuleError = UpdateFreshnessRuleErrors[keyof UpdateFreshnessRuleErrors]; export type UpdateFreshnessRuleResponses = { /** * Rule updated successfully */ 200: FreshnessRule; }; export type UpdateFreshnessRuleResponse = UpdateFreshnessRuleResponses[keyof UpdateFreshnessRuleResponses]; export type ResetTeamFreshnessSettingsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/freshness'; }; export type ResetTeamFreshnessSettingsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller may not change the team's settings */ 403: ErrorResponse; /** * Failed to reset the team's freshness settings */ 500: ErrorResponse; }; export type ResetTeamFreshnessSettingsError = ResetTeamFreshnessSettingsErrors[keyof ResetTeamFreshnessSettingsErrors]; export type ResetTeamFreshnessSettingsResponses = { /** * Settings reset (no content); the team now inherits the defaults */ 204: void; }; export type ResetTeamFreshnessSettingsResponse = ResetTeamFreshnessSettingsResponses[keyof ResetTeamFreshnessSettingsResponses]; export type GetTeamFreshnessSettingsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/freshness'; }; export type GetTeamFreshnessSettingsErrors = { /** * Invalid team_id */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to read the team's freshness settings */ 500: ErrorResponse; }; export type GetTeamFreshnessSettingsError = GetTeamFreshnessSettingsErrors[keyof GetTeamFreshnessSettingsErrors]; export type GetTeamFreshnessSettingsResponses = { /** * Settings retrieved successfully */ 200: TeamFreshnessSettings; }; export type GetTeamFreshnessSettingsResponse = GetTeamFreshnessSettingsResponses[keyof GetTeamFreshnessSettingsResponses]; export type UpdateTeamFreshnessSettingsData = { body: UpdateTeamFreshnessSettingsRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/freshness'; }; export type UpdateTeamFreshnessSettingsErrors = { /** * Invalid team_id or settings */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller may not change the team's settings */ 403: ErrorResponse; /** * Failed to update the team's freshness settings */ 500: ErrorResponse; }; export type UpdateTeamFreshnessSettingsError = UpdateTeamFreshnessSettingsErrors[keyof UpdateTeamFreshnessSettingsErrors]; export type UpdateTeamFreshnessSettingsResponses = { /** * Settings updated successfully */ 200: TeamFreshnessSettings; }; export type UpdateTeamFreshnessSettingsResponse = UpdateTeamFreshnessSettingsResponses[keyof UpdateTeamFreshnessSettingsResponses]; export type GetFreshnessOverTimeMetricsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * The reporting window. Defaults to 30d. */ range?: FreshnessMetricsRange; }; url: '/api/v1/{team_id}/freshness/metrics/over-time'; }; export type GetFreshnessOverTimeMetricsErrors = { /** * Invalid team_id or query parameter */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to build the team's freshness over-time metrics */ 500: ErrorResponse; }; export type GetFreshnessOverTimeMetricsError = GetFreshnessOverTimeMetricsErrors[keyof GetFreshnessOverTimeMetricsErrors]; export type GetFreshnessOverTimeMetricsResponses = { /** * Metrics retrieved successfully */ 200: FreshnessOverTimeMetricsResponse; }; export type GetFreshnessOverTimeMetricsResponse = GetFreshnessOverTimeMetricsResponses[keyof GetFreshnessOverTimeMetricsResponses]; export type GetFreshnessByTypeMetricsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/metrics/by-type'; }; export type GetFreshnessByTypeMetricsErrors = { /** * Invalid team_id or query parameter */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to build the team's freshness by-type metrics */ 500: ErrorResponse; }; export type GetFreshnessByTypeMetricsError = GetFreshnessByTypeMetricsErrors[keyof GetFreshnessByTypeMetricsErrors]; export type GetFreshnessByTypeMetricsResponses = { /** * Metrics retrieved successfully */ 200: FreshnessByTypeMetricsResponse; }; export type GetFreshnessByTypeMetricsResponse = GetFreshnessByTypeMetricsResponses[keyof GetFreshnessByTypeMetricsResponses]; export type GetFreshnessByProjectMetricsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/metrics/by-project'; }; export type GetFreshnessByProjectMetricsErrors = { /** * Invalid team_id or query parameter */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to build the team's freshness by-project metrics */ 500: ErrorResponse; }; export type GetFreshnessByProjectMetricsError = GetFreshnessByProjectMetricsErrors[keyof GetFreshnessByProjectMetricsErrors]; export type GetFreshnessByProjectMetricsResponses = { /** * Metrics retrieved successfully */ 200: FreshnessByProjectMetricsResponse; }; export type GetFreshnessByProjectMetricsResponse = GetFreshnessByProjectMetricsResponses[keyof GetFreshnessByProjectMetricsResponses]; export type GetFreshnessByRuleMetricsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/freshness/metrics/by-rule'; }; export type GetFreshnessByRuleMetricsErrors = { /** * Invalid team_id or query parameter */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to build the team's freshness by-rule metrics */ 500: ErrorResponse; }; export type GetFreshnessByRuleMetricsError = GetFreshnessByRuleMetricsErrors[keyof GetFreshnessByRuleMetricsErrors]; export type GetFreshnessByRuleMetricsResponses = { /** * Metrics retrieved successfully */ 200: FreshnessByRuleMetricsResponse; }; export type GetFreshnessByRuleMetricsResponse = GetFreshnessByRuleMetricsResponses[keyof GetFreshnessByRuleMetricsResponses]; export type ListFreshnessAuditData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Page number (1-based). The upper bound is not a storage limit — it keeps page * limit inside the range the offset arithmetic can represent, so an absurd page is rejected rather than silently wrapping around to the first one. * */ page?: number; /** * Entries per page */ limit?: number; }; url: '/api/v1/{team_id}/freshness/audit'; }; export type ListFreshnessAuditErrors = { /** * Invalid team_id or query parameter */ 400: ErrorResponse; /** * Authentication required */ 401: ErrorResponse; /** * Caller is not a member of the team */ 403: ErrorResponse; /** * Failed to list the team's freshness audit log */ 500: ErrorResponse; }; export type ListFreshnessAuditError = ListFreshnessAuditErrors[keyof ListFreshnessAuditErrors]; export type ListFreshnessAuditResponses = { /** * Audit log retrieved successfully */ 200: FreshnessAuditListResponse; }; export type ListFreshnessAuditResponse = ListFreshnessAuditResponses[keyof ListFreshnessAuditResponses]; export type ListEmbeddingProvidersSettingsData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers'; }; export type ListEmbeddingProvidersSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to retrieve embedding providers (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ListEmbeddingProvidersSettingsError = ListEmbeddingProvidersSettingsErrors[keyof ListEmbeddingProvidersSettingsErrors]; export type ListEmbeddingProvidersSettingsResponses = { /** * Embedding providers retrieved successfully */ 200: EmbeddingProviderArrayResponse; }; export type ListEmbeddingProvidersSettingsResponse = ListEmbeddingProvidersSettingsResponses[keyof ListEmbeddingProvidersSettingsResponses]; export type CreateEmbeddingProviderSettingsData = { body: CreateEmbeddingProviderRequest; path: { /** * Team that owns the embedding provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers'; }; export type CreateEmbeddingProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * A provider with the same name already exists (`PROVIDER_ALREADY_EXISTS`) */ 409: ErrorResponse; /** * Provider creation failed (`PROVIDER_CREATE_FAILED`) */ 500: ErrorResponse; }; export type CreateEmbeddingProviderSettingsError = CreateEmbeddingProviderSettingsErrors[keyof CreateEmbeddingProviderSettingsErrors]; export type CreateEmbeddingProviderSettingsResponses = { /** * Embedding provider created successfully */ 200: EmbeddingProviderResponse; }; export type CreateEmbeddingProviderSettingsResponse = CreateEmbeddingProviderSettingsResponses[keyof CreateEmbeddingProviderSettingsResponses]; export type GetEmbeddingCoverageSettingsData = { body?: never; path: { /** * Team whose embedding coverage is reported. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/coverage'; }; export type GetEmbeddingCoverageSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to retrieve embedding coverage (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type GetEmbeddingCoverageSettingsError = GetEmbeddingCoverageSettingsErrors[keyof GetEmbeddingCoverageSettingsErrors]; export type GetEmbeddingCoverageSettingsResponses = { /** * Embedding coverage retrieved successfully */ 200: EmbeddingCoverageResponse; }; export type GetEmbeddingCoverageSettingsResponse = GetEmbeddingCoverageSettingsResponses[keyof GetEmbeddingCoverageSettingsResponses]; export type DeleteEmbeddingProviderSettingsData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/{id}'; }; export type DeleteEmbeddingProviderSettingsErrors = { /** * Cannot delete the last embedding provider (`PROVIDER_LAST_DELETE_BLOCKED`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider deletion failed (`PROVIDER_DELETE_FAILED`) */ 500: ErrorResponse; }; export type DeleteEmbeddingProviderSettingsError = DeleteEmbeddingProviderSettingsErrors[keyof DeleteEmbeddingProviderSettingsErrors]; export type DeleteEmbeddingProviderSettingsResponses = { /** * Embedding provider deleted successfully (no body) */ 204: void; }; export type DeleteEmbeddingProviderSettingsResponse = DeleteEmbeddingProviderSettingsResponses[keyof DeleteEmbeddingProviderSettingsResponses]; export type GetEmbeddingProviderSettingsData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/{id}'; }; export type GetEmbeddingProviderSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Failed to retrieve embedding provider (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type GetEmbeddingProviderSettingsError = GetEmbeddingProviderSettingsErrors[keyof GetEmbeddingProviderSettingsErrors]; export type GetEmbeddingProviderSettingsResponses = { /** * Embedding provider retrieved successfully */ 200: EmbeddingProviderResponse; }; export type GetEmbeddingProviderSettingsResponse = GetEmbeddingProviderSettingsResponses[keyof GetEmbeddingProviderSettingsResponses]; export type UpdateEmbeddingProviderSettingsData = { body: UpdateEmbeddingProviderRequest; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/{id}'; }; export type UpdateEmbeddingProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider update failed (`PROVIDER_UPDATE_FAILED`) */ 500: ErrorResponse; }; export type UpdateEmbeddingProviderSettingsError = UpdateEmbeddingProviderSettingsErrors[keyof UpdateEmbeddingProviderSettingsErrors]; export type UpdateEmbeddingProviderSettingsResponses = { /** * Embedding provider updated successfully */ 200: EmbeddingProviderResponse; }; export type UpdateEmbeddingProviderSettingsResponse = UpdateEmbeddingProviderSettingsResponses[keyof UpdateEmbeddingProviderSettingsResponses]; export type ReprocessEmbeddingProviderSettingsData = { body?: never; path: { /** * Team that owns the embedding provider(s). */ team_id: string; /** * Embedding provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/{id}/reprocess'; }; export type ReprocessEmbeddingProviderSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Embedding provider not found (`PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Failed to load the provider before reprocess (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ReprocessEmbeddingProviderSettingsError = ReprocessEmbeddingProviderSettingsErrors[keyof ReprocessEmbeddingProviderSettingsErrors]; export type ReprocessEmbeddingProviderSettingsResponses = { /** * Reprocess accepted; embeddings are regenerated in the background. */ 202: SuccessResponse; }; export type ReprocessEmbeddingProviderSettingsResponse = ReprocessEmbeddingProviderSettingsResponses[keyof ReprocessEmbeddingProviderSettingsResponses]; export type ValidateEmbeddingProviderSettingsData = { body: ValidateEmbeddingProviderRequest; path: { /** * Team that owns the embedding provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/validate'; }; export type ValidateEmbeddingProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Validation failed due to an internal service error (`INTERNAL_ERROR`) */ 500: ErrorResponse; }; export type ValidateEmbeddingProviderSettingsError = ValidateEmbeddingProviderSettingsErrors[keyof ValidateEmbeddingProviderSettingsErrors]; export type ValidateEmbeddingProviderSettingsResponses = { /** * Validation completed (check `is_valid` for the outcome) */ 200: ValidateEmbeddingProviderResponse; }; export type ValidateEmbeddingProviderSettingsResponse = ValidateEmbeddingProviderSettingsResponses[keyof ValidateEmbeddingProviderSettingsResponses]; export type ClearEmbeddingsSettingsData = { body?: never; path: { /** * Team whose stored embeddings are cleared. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/embeddings'; }; export type ClearEmbeddingsSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Failed to clear embeddings (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ClearEmbeddingsSettingsError = ClearEmbeddingsSettingsErrors[keyof ClearEmbeddingsSettingsErrors]; export type ClearEmbeddingsSettingsResponses = { /** * Embeddings cleared; body reports how many rows were deleted. */ 200: ClearEmbeddingsResponse; }; export type ClearEmbeddingsSettingsResponse = ClearEmbeddingsSettingsResponses[keyof ClearEmbeddingsSettingsResponses]; export type CopyEmbeddingProviderFromTeamData = { body: CopyEmbeddingProviderRequest; path: { /** * Destination team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/embedding-providers/copy'; }; export type CopyEmbeddingProviderFromTeamErrors = { /** * Missing or malformed body, missing/malformed `source_team_id` or `source_provider_id`, source equal to destination (`BAD_REQUEST`), or an override sent empty or over-long (`PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller cannot manage provider settings in the destination team or in the source team (`FORBIDDEN`). The two are deliberately indistinguishable, so the response never reveals whether the source team exists. */ 403: ErrorResponse; /** * No such provider in the source team (`PROVIDER_NOT_FOUND`). Only reachable once the caller is authorized on both teams, so it leaks nothing. */ 404: ErrorResponse; /** * The destination team already holds the requested name (`PROVIDER_ALREADY_EXISTS`). Only reachable for a caller-supplied `name`; an inherited one is disambiguated instead. */ 409: ErrorResponse; /** * Copy failed (`INTERNAL_ERROR`) */ 500: ErrorResponse; }; export type CopyEmbeddingProviderFromTeamError = CopyEmbeddingProviderFromTeamErrors[keyof CopyEmbeddingProviderFromTeamErrors]; export type CopyEmbeddingProviderFromTeamResponses = { /** * Provider copied into the destination team */ 200: CopyEmbeddingProviderResponse; }; export type CopyEmbeddingProviderFromTeamResponse = CopyEmbeddingProviderFromTeamResponses[keyof CopyEmbeddingProviderFromTeamResponses]; export type DeleteGitHubAppConfigData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/app'; }; export type DeleteGitHubAppConfigErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type DeleteGitHubAppConfigError = DeleteGitHubAppConfigErrors[keyof DeleteGitHubAppConfigErrors]; export type DeleteGitHubAppConfigResponses = { /** * GitHub App configuration deleted */ 204: void; }; export type DeleteGitHubAppConfigResponse = DeleteGitHubAppConfigResponses[keyof DeleteGitHubAppConfigResponses]; export type GetGitHubAppConfigData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/app'; }; export type GetGitHubAppConfigErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type GetGitHubAppConfigError = GetGitHubAppConfigErrors[keyof GetGitHubAppConfigErrors]; export type GetGitHubAppConfigResponses = { /** * The team's GitHub App configuration */ 200: GitHubAppConfigResponse; }; export type GetGitHubAppConfigResponse = GetGitHubAppConfigResponses[keyof GetGitHubAppConfigResponses]; export type CreateGitHubAppConfigData = { body: CreateGitHubAppConfigRequest; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/app'; }; export type CreateGitHubAppConfigErrors = { /** * Malformed JSON body (`BAD_REQUEST`), missing required fields, or an unparseable private key (`VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team already has an App configured (`GITHUB_APP_CONFIG_EXISTS`), or another team already registered this `app_id` (`GITHUB_APP_ALREADY_REGISTERED`) — a GitHub App has a single webhook URL, so it cannot be shared across teams */ 409: ErrorResponse; }; export type CreateGitHubAppConfigError = CreateGitHubAppConfigErrors[keyof CreateGitHubAppConfigErrors]; export type CreateGitHubAppConfigResponses = { /** * GitHub App registered. This is the only response that carries the plaintext `webhook_secret`. */ 200: CreateGitHubAppConfigResponse; }; export type CreateGitHubAppConfigResponse2 = CreateGitHubAppConfigResponses[keyof CreateGitHubAppConfigResponses]; export type UpdateGitHubAppConfigData = { body: UpdateGitHubAppConfigRequest; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/app'; }; export type UpdateGitHubAppConfigErrors = { /** * Malformed JSON body (`BAD_REQUEST`), an explicitly empty field, or an unparseable private key (`VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`), another team already registered this `app_id` (`GITHUB_APP_ALREADY_REGISTERED`), or the configuration was modified concurrently (`GITHUB_APP_CONFIG_CONFLICT`) */ 409: ErrorResponse; }; export type UpdateGitHubAppConfigError = UpdateGitHubAppConfigErrors[keyof UpdateGitHubAppConfigErrors]; export type UpdateGitHubAppConfigResponses = { /** * GitHub App configuration updated */ 200: GitHubAppConfigResponse; }; export type UpdateGitHubAppConfigResponse = UpdateGitHubAppConfigResponses[keyof UpdateGitHubAppConfigResponses]; export type ValidateGitHubAppConfigData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/app/validate'; }; export type ValidateGitHubAppConfigErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type ValidateGitHubAppConfigError = ValidateGitHubAppConfigErrors[keyof ValidateGitHubAppConfigErrors]; export type ValidateGitHubAppConfigResponses = { /** * Validation result (successful or not) */ 200: ValidateGitHubAppConfigResponse; }; export type ValidateGitHubAppConfigResponse2 = ValidateGitHubAppConfigResponses[keyof ValidateGitHubAppConfigResponses]; export type RotateGitHubAppWebhookTokenData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/integrations/github/app/rotate-webhook-token'; }; export type RotateGitHubAppWebhookTokenErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type RotateGitHubAppWebhookTokenError = RotateGitHubAppWebhookTokenErrors[keyof RotateGitHubAppWebhookTokenErrors]; export type RotateGitHubAppWebhookTokenResponses = { /** * Token rotated; the response carries the new `webhook_url` */ 200: GitHubAppConfigResponse; }; export type RotateGitHubAppWebhookTokenResponse = RotateGitHubAppWebhookTokenResponses[keyof RotateGitHubAppWebhookTokenResponses]; export type DeleteGitHubAppConfigSettingsData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/github-app'; }; export type DeleteGitHubAppConfigSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type DeleteGitHubAppConfigSettingsError = DeleteGitHubAppConfigSettingsErrors[keyof DeleteGitHubAppConfigSettingsErrors]; export type DeleteGitHubAppConfigSettingsResponses = { /** * GitHub App configuration deleted */ 204: void; }; export type DeleteGitHubAppConfigSettingsResponse = DeleteGitHubAppConfigSettingsResponses[keyof DeleteGitHubAppConfigSettingsResponses]; export type GetGitHubAppConfigSettingsData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/github-app'; }; export type GetGitHubAppConfigSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type GetGitHubAppConfigSettingsError = GetGitHubAppConfigSettingsErrors[keyof GetGitHubAppConfigSettingsErrors]; export type GetGitHubAppConfigSettingsResponses = { /** * The team's GitHub App configuration */ 200: GitHubAppConfigResponse; }; export type GetGitHubAppConfigSettingsResponse = GetGitHubAppConfigSettingsResponses[keyof GetGitHubAppConfigSettingsResponses]; export type CreateGitHubAppConfigSettingsData = { body: CreateGitHubAppConfigRequest; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/github-app'; }; export type CreateGitHubAppConfigSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`), missing required fields, or an unparseable private key (`VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team already has an App configured (`GITHUB_APP_CONFIG_EXISTS`), or another team already registered this `app_id` (`GITHUB_APP_ALREADY_REGISTERED`) — a GitHub App has a single webhook URL, so it cannot be shared across teams */ 409: ErrorResponse; }; export type CreateGitHubAppConfigSettingsError = CreateGitHubAppConfigSettingsErrors[keyof CreateGitHubAppConfigSettingsErrors]; export type CreateGitHubAppConfigSettingsResponses = { /** * GitHub App registered. This is the only response that carries the plaintext `webhook_secret`. */ 200: CreateGitHubAppConfigResponse; }; export type CreateGitHubAppConfigSettingsResponse = CreateGitHubAppConfigSettingsResponses[keyof CreateGitHubAppConfigSettingsResponses]; export type UpdateGitHubAppConfigSettingsData = { body: UpdateGitHubAppConfigRequest; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/github-app'; }; export type UpdateGitHubAppConfigSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`), an explicitly empty field, or an unparseable private key (`VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`), another team already registered this `app_id` (`GITHUB_APP_ALREADY_REGISTERED`), or the configuration was modified concurrently (`GITHUB_APP_CONFIG_CONFLICT`) */ 409: ErrorResponse; }; export type UpdateGitHubAppConfigSettingsError = UpdateGitHubAppConfigSettingsErrors[keyof UpdateGitHubAppConfigSettingsErrors]; export type UpdateGitHubAppConfigSettingsResponses = { /** * GitHub App configuration updated */ 200: GitHubAppConfigResponse; }; export type UpdateGitHubAppConfigSettingsResponse = UpdateGitHubAppConfigSettingsResponses[keyof UpdateGitHubAppConfigSettingsResponses]; export type ValidateGitHubAppConfigSettingsData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/github-app/validate'; }; export type ValidateGitHubAppConfigSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type ValidateGitHubAppConfigSettingsError = ValidateGitHubAppConfigSettingsErrors[keyof ValidateGitHubAppConfigSettingsErrors]; export type ValidateGitHubAppConfigSettingsResponses = { /** * Validation result (successful or not) */ 200: ValidateGitHubAppConfigResponse; }; export type ValidateGitHubAppConfigSettingsResponse = ValidateGitHubAppConfigSettingsResponses[keyof ValidateGitHubAppConfigSettingsResponses]; export type RotateGitHubAppWebhookTokenSettingsData = { body?: never; path: { /** * Team that owns the GitHub App registration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/github-app/rotate-webhook-token'; }; export type RotateGitHubAppWebhookTokenSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing the GitHub App requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no GitHub App configured (`GITHUB_APP_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type RotateGitHubAppWebhookTokenSettingsError = RotateGitHubAppWebhookTokenSettingsErrors[keyof RotateGitHubAppWebhookTokenSettingsErrors]; export type RotateGitHubAppWebhookTokenSettingsResponses = { /** * Token rotated; the response carries the new `webhook_url` */ 200: GitHubAppConfigResponse; }; export type RotateGitHubAppWebhookTokenSettingsResponse = RotateGitHubAppWebhookTokenSettingsResponses[keyof RotateGitHubAppWebhookTokenSettingsResponses]; export type DeleteTeamEmailProviderData = { body?: never; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/email-provider'; }; export type DeleteTeamEmailProviderErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - configuring the team's email provider requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no email provider of its own (`TEAM_EMAIL_PROVIDER_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type DeleteTeamEmailProviderError = DeleteTeamEmailProviderErrors[keyof DeleteTeamEmailProviderErrors]; export type DeleteTeamEmailProviderResponses = { /** * Provider removed; the team now uses the instance provider */ 204: void; }; export type DeleteTeamEmailProviderResponse = DeleteTeamEmailProviderResponses[keyof DeleteTeamEmailProviderResponses]; export type GetTeamEmailProviderData = { body?: never; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/email-provider'; }; export type GetTeamEmailProviderErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type GetTeamEmailProviderError = GetTeamEmailProviderErrors[keyof GetTeamEmailProviderErrors]; export type GetTeamEmailProviderResponses = { /** * The email configuration in force for the team */ 200: TeamEmailProviderResponse; }; export type GetTeamEmailProviderResponse = GetTeamEmailProviderResponses[keyof GetTeamEmailProviderResponses]; export type UpsertTeamEmailProviderData = { body: UpsertTeamEmailProviderRequest; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/email-provider'; }; export type UpsertTeamEmailProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`), or an invalid configuration (`TEAM_EMAIL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) — an unknown provider type, a missing or mismatched settings block, an empty `secret`, a malformed address, or a destination that is not allowed */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - configuring the team's email provider requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; }; export type UpsertTeamEmailProviderError = UpsertTeamEmailProviderErrors[keyof UpsertTeamEmailProviderErrors]; export type UpsertTeamEmailProviderResponses = { /** * The stored configuration */ 200: TeamEmailProviderResponse; }; export type UpsertTeamEmailProviderResponse = UpsertTeamEmailProviderResponses[keyof UpsertTeamEmailProviderResponses]; export type TestTeamEmailProviderData = { body: UpsertTeamEmailProviderRequest; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/email-provider/test'; }; export type TestTeamEmailProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`), or an invalid configuration (`TEAM_EMAIL_PROVIDER_VALIDATION_FAILED` with `validation_errors`). `secret` is always required here, since there is no stored credential to fall back on */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - testing the team's email provider requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; }; export type TestTeamEmailProviderError = TestTeamEmailProviderErrors[keyof TestTeamEmailProviderErrors]; export type TestTeamEmailProviderResponses = { /** * Test outcome (successful or not) */ 200: TeamEmailProviderTestResponse; }; export type TestTeamEmailProviderResponse = TestTeamEmailProviderResponses[keyof TestTeamEmailProviderResponses]; export type DeleteTeamEmailProviderSettingsData = { body?: never; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/email-provider'; }; export type DeleteTeamEmailProviderSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - configuring the team's email provider requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * The team has no email provider of its own (`TEAM_EMAIL_PROVIDER_NOT_CONFIGURED`) */ 409: ErrorResponse; }; export type DeleteTeamEmailProviderSettingsError = DeleteTeamEmailProviderSettingsErrors[keyof DeleteTeamEmailProviderSettingsErrors]; export type DeleteTeamEmailProviderSettingsResponses = { /** * Provider removed; the team now uses the instance provider */ 204: void; }; export type DeleteTeamEmailProviderSettingsResponse = DeleteTeamEmailProviderSettingsResponses[keyof DeleteTeamEmailProviderSettingsResponses]; export type GetTeamEmailProviderSettingsData = { body?: never; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/email-provider'; }; export type GetTeamEmailProviderSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type GetTeamEmailProviderSettingsError = GetTeamEmailProviderSettingsErrors[keyof GetTeamEmailProviderSettingsErrors]; export type GetTeamEmailProviderSettingsResponses = { /** * The email configuration in force for the team */ 200: TeamEmailProviderResponse; }; export type GetTeamEmailProviderSettingsResponse = GetTeamEmailProviderSettingsResponses[keyof GetTeamEmailProviderSettingsResponses]; export type UpsertTeamEmailProviderSettingsData = { body: UpsertTeamEmailProviderRequest; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/email-provider'; }; export type UpsertTeamEmailProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`), or an invalid configuration (`TEAM_EMAIL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) — an unknown provider type, a missing or mismatched settings block, an empty `secret`, a malformed address, or a destination that is not allowed */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - configuring the team's email provider requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; }; export type UpsertTeamEmailProviderSettingsError = UpsertTeamEmailProviderSettingsErrors[keyof UpsertTeamEmailProviderSettingsErrors]; export type UpsertTeamEmailProviderSettingsResponses = { /** * The stored configuration */ 200: TeamEmailProviderResponse; }; export type UpsertTeamEmailProviderSettingsResponse = UpsertTeamEmailProviderSettingsResponses[keyof UpsertTeamEmailProviderSettingsResponses]; export type TestTeamEmailProviderSettingsData = { body: UpsertTeamEmailProviderRequest; path: { /** * Team that owns the email provider configuration. */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/email-provider/test'; }; export type TestTeamEmailProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`), or an invalid configuration (`TEAM_EMAIL_PROVIDER_VALIDATION_FAILED` with `validation_errors`). `secret` is always required here, since there is no stored credential to fall back on */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - testing the team's email provider requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; }; export type TestTeamEmailProviderSettingsError = TestTeamEmailProviderSettingsErrors[keyof TestTeamEmailProviderSettingsErrors]; export type TestTeamEmailProviderSettingsResponses = { /** * Test outcome (successful or not) */ 200: TeamEmailProviderTestResponse; }; export type TestTeamEmailProviderSettingsResponse = TestTeamEmailProviderSettingsResponses[keyof TestTeamEmailProviderSettingsResponses]; export type ListModelProvidersData = { body?: never; path: { /** * Team that owns the model provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/model-providers'; }; export type ListModelProvidersErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to retrieve model providers (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ListModelProvidersError = ListModelProvidersErrors[keyof ListModelProvidersErrors]; export type ListModelProvidersResponses = { /** * Model providers retrieved successfully */ 200: ModelProviderResponseList; }; export type ListModelProvidersResponse = ListModelProvidersResponses[keyof ListModelProvidersResponses]; export type CreateModelProviderData = { body: CreateModelProviderRequest; path: { /** * Team that owns the model provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/model-providers'; }; export type CreateModelProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`MODEL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * A provider with the same name already exists (`MODEL_PROVIDER_ALREADY_EXISTS`) */ 409: ErrorResponse; /** * Provider creation failed (`MODEL_PROVIDER_CREATE_FAILED`) */ 500: ErrorResponse; }; export type CreateModelProviderError = CreateModelProviderErrors[keyof CreateModelProviderErrors]; export type CreateModelProviderResponses = { /** * Model provider created successfully */ 200: ModelProviderResponse; }; export type CreateModelProviderResponse = CreateModelProviderResponses[keyof CreateModelProviderResponses]; export type DeleteModelProviderData = { body?: never; path: { /** * Team that owns the model provider(s). */ team_id: string; /** * Model provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/model-providers/{id}'; }; export type DeleteModelProviderErrors = { /** * Cannot delete the last model provider (`MODEL_PROVIDER_LAST_DELETE_BLOCKED`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Model provider not found (`MODEL_PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider deletion failed (`MODEL_PROVIDER_DELETE_FAILED`) */ 500: ErrorResponse; }; export type DeleteModelProviderError = DeleteModelProviderErrors[keyof DeleteModelProviderErrors]; export type DeleteModelProviderResponses = { /** * Model provider deleted successfully (no body) */ 204: void; }; export type DeleteModelProviderResponse = DeleteModelProviderResponses[keyof DeleteModelProviderResponses]; export type GetModelProviderData = { body?: never; path: { /** * Team that owns the model provider(s). */ team_id: string; /** * Model provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/model-providers/{id}'; }; export type GetModelProviderErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Model provider not found (`MODEL_PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Failed to retrieve model provider (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type GetModelProviderError = GetModelProviderErrors[keyof GetModelProviderErrors]; export type GetModelProviderResponses = { /** * Model provider retrieved successfully */ 200: ModelProviderResponse; }; export type GetModelProviderResponse = GetModelProviderResponses[keyof GetModelProviderResponses]; export type UpdateModelProviderData = { body: UpdateModelProviderRequest; path: { /** * Team that owns the model provider(s). */ team_id: string; /** * Model provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/model-providers/{id}'; }; export type UpdateModelProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Model provider not found (`MODEL_PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider update failed (`MODEL_PROVIDER_UPDATE_FAILED`) */ 500: ErrorResponse; }; export type UpdateModelProviderError = UpdateModelProviderErrors[keyof UpdateModelProviderErrors]; export type UpdateModelProviderResponses = { /** * Model provider updated successfully */ 200: ModelProviderResponse; }; export type UpdateModelProviderResponse = UpdateModelProviderResponses[keyof UpdateModelProviderResponses]; export type ValidateModelProviderData = { body: ValidateModelProviderRequest; path: { /** * Team that owns the model provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/model-providers/validate'; }; export type ValidateModelProviderErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`MODEL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Validation failed due to an internal service error (`INTERNAL_ERROR`) */ 500: ErrorResponse; }; export type ValidateModelProviderError = ValidateModelProviderErrors[keyof ValidateModelProviderErrors]; export type ValidateModelProviderResponses = { /** * Validation completed (check `is_valid` for the outcome) */ 200: ValidateModelProviderResponse; }; export type ValidateModelProviderResponse2 = ValidateModelProviderResponses[keyof ValidateModelProviderResponses]; export type ListModelProvidersSettingsData = { body?: never; path: { /** * Team that owns the model provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers'; }; export type ListModelProvidersSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Failed to retrieve model providers (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type ListModelProvidersSettingsError = ListModelProvidersSettingsErrors[keyof ListModelProvidersSettingsErrors]; export type ListModelProvidersSettingsResponses = { /** * Model providers retrieved successfully */ 200: ModelProviderResponseList; }; export type ListModelProvidersSettingsResponse = ListModelProvidersSettingsResponses[keyof ListModelProvidersSettingsResponses]; export type CreateModelProviderSettingsData = { body: CreateModelProviderRequest; path: { /** * Team that owns the model provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers'; }; export type CreateModelProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`MODEL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * A provider with the same name already exists (`MODEL_PROVIDER_ALREADY_EXISTS`) */ 409: ErrorResponse; /** * Provider creation failed (`MODEL_PROVIDER_CREATE_FAILED`) */ 500: ErrorResponse; }; export type CreateModelProviderSettingsError = CreateModelProviderSettingsErrors[keyof CreateModelProviderSettingsErrors]; export type CreateModelProviderSettingsResponses = { /** * Model provider created successfully */ 200: ModelProviderResponse; }; export type CreateModelProviderSettingsResponse = CreateModelProviderSettingsResponses[keyof CreateModelProviderSettingsResponses]; export type DeleteModelProviderSettingsData = { body?: never; path: { /** * Team that owns the model provider(s). */ team_id: string; /** * Model provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers/{id}'; }; export type DeleteModelProviderSettingsErrors = { /** * Cannot delete the last model provider (`MODEL_PROVIDER_LAST_DELETE_BLOCKED`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Model provider not found (`MODEL_PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider deletion failed (`MODEL_PROVIDER_DELETE_FAILED`) */ 500: ErrorResponse; }; export type DeleteModelProviderSettingsError = DeleteModelProviderSettingsErrors[keyof DeleteModelProviderSettingsErrors]; export type DeleteModelProviderSettingsResponses = { /** * Model provider deleted successfully (no body) */ 204: void; }; export type DeleteModelProviderSettingsResponse = DeleteModelProviderSettingsResponses[keyof DeleteModelProviderSettingsResponses]; export type GetModelProviderSettingsData = { body?: never; path: { /** * Team that owns the model provider(s). */ team_id: string; /** * Model provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers/{id}'; }; export type GetModelProviderSettingsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Model provider not found (`MODEL_PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Failed to retrieve model provider (`DATABASE_ERROR`) */ 500: ErrorResponse; }; export type GetModelProviderSettingsError = GetModelProviderSettingsErrors[keyof GetModelProviderSettingsErrors]; export type GetModelProviderSettingsResponses = { /** * Model provider retrieved successfully */ 200: ModelProviderResponse; }; export type GetModelProviderSettingsResponse = GetModelProviderSettingsResponses[keyof GetModelProviderSettingsResponses]; export type UpdateModelProviderSettingsData = { body: UpdateModelProviderRequest; path: { /** * Team that owns the model provider(s). */ team_id: string; /** * Model provider ID */ id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers/{id}'; }; export type UpdateModelProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Model provider not found (`MODEL_PROVIDER_NOT_FOUND`) */ 404: ErrorResponse; /** * Provider update failed (`MODEL_PROVIDER_UPDATE_FAILED`) */ 500: ErrorResponse; }; export type UpdateModelProviderSettingsError = UpdateModelProviderSettingsErrors[keyof UpdateModelProviderSettingsErrors]; export type UpdateModelProviderSettingsResponses = { /** * Model provider updated successfully */ 200: ModelProviderResponse; }; export type UpdateModelProviderSettingsResponse = UpdateModelProviderSettingsResponses[keyof UpdateModelProviderSettingsResponses]; export type ValidateModelProviderSettingsData = { body: ValidateModelProviderRequest; path: { /** * Team that owns the model provider(s). */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers/validate'; }; export type ValidateModelProviderSettingsErrors = { /** * Malformed JSON body (`BAD_REQUEST`) or missing required fields (`MODEL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden - managing provider settings requires team owner/admin (`FORBIDDEN`) */ 403: ErrorResponse; /** * Validation failed due to an internal service error (`INTERNAL_ERROR`) */ 500: ErrorResponse; }; export type ValidateModelProviderSettingsError = ValidateModelProviderSettingsErrors[keyof ValidateModelProviderSettingsErrors]; export type ValidateModelProviderSettingsResponses = { /** * Validation completed (check `is_valid` for the outcome) */ 200: ValidateModelProviderResponse; }; export type ValidateModelProviderSettingsResponse = ValidateModelProviderSettingsResponses[keyof ValidateModelProviderSettingsResponses]; export type CopyModelProviderFromTeamData = { body: CopyModelProviderRequest; path: { /** * Destination team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/settings/model-providers/copy'; }; export type CopyModelProviderFromTeamErrors = { /** * Missing or malformed body, missing/malformed `source_team_id` or `source_provider_id`, source equal to destination (`BAD_REQUEST`), or an override sent empty (`MODEL_PROVIDER_VALIDATION_FAILED` with `validation_errors`) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Caller cannot manage provider settings in the destination team or in the source team (`FORBIDDEN`). The two are deliberately indistinguishable, so the response never reveals whether the source team exists. */ 403: ErrorResponse; /** * No such provider in the source team (`MODEL_PROVIDER_NOT_FOUND`). Only reachable once the caller is authorized on both teams, so it leaks nothing. */ 404: ErrorResponse; /** * The chosen name is already taken in the destination team (`MODEL_PROVIDER_ALREADY_EXISTS`). Normally that means a caller-supplied `name`, since an omitted one is disambiguated first — but a disambiguated name can still land here if another writer claims it in between, or if every generated variant is already taken. */ 409: ErrorResponse; /** * Failed to copy the model provider (`INTERNAL_ERROR`) */ 500: ErrorResponse; }; export type CopyModelProviderFromTeamError = CopyModelProviderFromTeamErrors[keyof CopyModelProviderFromTeamErrors]; export type CopyModelProviderFromTeamResponses = { /** * Provider copied into the destination team */ 200: ModelProviderResponse; }; export type CopyModelProviderFromTeamResponse = CopyModelProviderFromTeamResponses[keyof CopyModelProviderFromTeamResponses]; export type ListProjectsData = { body?: never; path: { /** * Team identifier */ team_id: string; }; query?: { /** * Search term to filter projects */ search?: string; /** * Field to sort by */ sort_by?: string; /** * Sort direction (asc or desc) */ sort_order?: string; /** * Page number (1-based) */ page?: number; /** * Number of items per page (values above 100 are clamped to 100) */ limit?: number; }; url: '/api/v1/{team_id}/projects'; }; export type ListProjectsErrors = { /** * team_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListProjectsError = ListProjectsErrors[keyof ListProjectsErrors]; export type ListProjectsResponses = { /** * Projects retrieved successfully */ 200: ProjectListResponse; }; export type ListProjectsResponse = ListProjectsResponses[keyof ListProjectsResponses]; export type CreateProjectData = { body: CreateProjectRequest; path: { /** * Team identifier */ team_id: string; }; query?: never; url: '/api/v1/{team_id}/projects'; }; export type CreateProjectErrors = { /** * Invalid request body, validation failure, or team_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Project with the same slug already exists */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CreateProjectError = CreateProjectErrors[keyof CreateProjectErrors]; export type CreateProjectResponses = { /** * Project created successfully */ 201: Project; }; export type CreateProjectResponse = CreateProjectResponses[keyof CreateProjectResponses]; export type DeleteProjectData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project slug (URL-encoded) */ slug: string; }; query?: never; url: '/api/v1/{team_id}/projects/{slug}'; }; export type DeleteProjectErrors = { /** * Cannot delete the last project in the team, or invalid slug encoding / team_id */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Project not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type DeleteProjectError = DeleteProjectErrors[keyof DeleteProjectErrors]; export type DeleteProjectResponses = { /** * Project deleted successfully */ 204: void; }; export type DeleteProjectResponse = DeleteProjectResponses[keyof DeleteProjectResponses]; export type GetProjectData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Project slug (URL-encoded) */ slug: string; }; query?: never; url: '/api/v1/{team_id}/projects/{slug}'; }; export type GetProjectErrors = { /** * Invalid slug encoding or team_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Project not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetProjectError = GetProjectErrors[keyof GetProjectErrors]; export type GetProjectResponses = { /** * Project retrieved successfully */ 200: Project; }; export type GetProjectResponse = GetProjectResponses[keyof GetProjectResponses]; export type UpdateProjectData = { body: UpdateProjectRequest; path: { /** * Team identifier */ team_id: string; /** * Project slug (URL-encoded) */ slug: string; }; query?: never; url: '/api/v1/{team_id}/projects/{slug}'; }; export type UpdateProjectErrors = { /** * Invalid request body, validation failure, cross-team move attempted, or invalid slug encoding */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member) */ 403: ErrorResponse; /** * Project not found */ 404: ErrorResponse; /** * Slug already exists, or the project was modified by another request (version mismatch) */ 409: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type UpdateProjectError = UpdateProjectErrors[keyof UpdateProjectErrors]; export type UpdateProjectResponses = { /** * Project updated successfully */ 200: Project; }; export type UpdateProjectResponse = UpdateProjectResponses[keyof UpdateProjectResponses]; export type GetProjectMigrationInventoryData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Source project identifier */ project_id: string; }; query?: never; url: '/api/v1/{team_id}/projects/{project_id}/migration/inventory'; }; export type GetProjectMigrationInventoryErrors = { /** * project_id or team_id is not a valid UUID */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member, or project does not belong to the specified team) */ 403: ErrorResponse; /** * Project not found or not accessible */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetProjectMigrationInventoryError = GetProjectMigrationInventoryErrors[keyof GetProjectMigrationInventoryErrors]; export type GetProjectMigrationInventoryResponses = { /** * Migration inventory retrieved successfully */ 200: MigrationInventory; }; export type GetProjectMigrationInventoryResponse = GetProjectMigrationInventoryResponses[keyof GetProjectMigrationInventoryResponses]; export type MigrateProjectData = { body: MigrationRequest; path: { /** * Team identifier */ team_id: string; /** * Source project identifier */ project_id: string; }; query?: never; url: '/api/v1/{team_id}/projects/{project_id}/migration'; }; export type MigrateProjectErrors = { /** * Invalid request body, invalid UUID, invalid conflict_policy, or cross-team migration attempted */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden (not a team member, or project does not belong to the specified team) */ 403: ErrorResponse; /** * Source or destination project not found or not accessible */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type MigrateProjectError = MigrateProjectErrors[keyof MigrateProjectErrors]; export type MigrateProjectResponses = { /** * Migration completed (individual resources may still be reported as skipped or failed) */ 200: MigrationResult; }; export type MigrateProjectResponse = MigrateProjectResponses[keyof MigrateProjectResponses]; export type ListActivitiesData = { body?: never; path?: never; query?: { /** * Page number (1-based); converted to an offset using the current limit */ page?: number; /** * Number of items per page (values outside 1-100 are ignored) */ limit?: number; /** * Explicit result offset (takes precedence over page when both are provided) */ offset?: number; /** * Filter by activity type (e.g. prompt_created) */ activity_type?: string; /** * Filter by entity type (e.g. prompt) */ entity_type?: string; /** * Filter by entity identifier */ entity_id?: string; /** * Filter by session identifier */ session_id?: string; /** * Free-text search in activity descriptions */ search?: string; /** * Include activities from this date (YYYY-MM-DD, inclusive) */ date_from?: string; /** * Include activities up to this date (YYYY-MM-DD, inclusive end of day) */ date_to?: string; }; url: '/api/v1/activities'; }; export type ListActivitiesErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListActivitiesError = ListActivitiesErrors[keyof ListActivitiesErrors]; export type ListActivitiesResponses = { /** * Activities retrieved successfully */ 200: ActivityListEnvelope; }; export type ListActivitiesResponse = ListActivitiesResponses[keyof ListActivitiesResponses]; export type CreateActivityData = { body: CreateActivityRequest; path?: never; query?: never; url: '/api/v1/activities'; }; export type CreateActivityErrors = { /** * Invalid JSON payload or missing required field (activity_type, entity_type, description) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CreateActivityError = CreateActivityErrors[keyof CreateActivityErrors]; export type CreateActivityResponses = { /** * Activity created successfully */ 201: ActivityEnvelope; }; export type CreateActivityResponse = CreateActivityResponses[keyof CreateActivityResponses]; export type GetActivityStatsData = { body?: never; path?: never; query?: never; url: '/api/v1/activities/stats'; }; export type GetActivityStatsErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetActivityStatsError = GetActivityStatsErrors[keyof GetActivityStatsErrors]; export type GetActivityStatsResponses = { /** * Activity statistics retrieved successfully */ 200: ActivityStatsEnvelope; }; export type GetActivityStatsResponse = GetActivityStatsResponses[keyof GetActivityStatsResponses]; export type GetActivityTypesData = { body?: never; path?: never; query?: never; url: '/api/v1/activities/types'; }; export type GetActivityTypesErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type GetActivityTypesError = GetActivityTypesErrors[keyof GetActivityTypesErrors]; export type GetActivityTypesResponses = { /** * Activity and entity types retrieved successfully */ 200: ActivityTypesEnvelope; }; export type GetActivityTypesResponse = GetActivityTypesResponses[keyof GetActivityTypesResponses]; export type GetActivityEntityTypesData = { body?: never; path?: never; query?: never; url: '/api/v1/activities/entity-types'; }; export type GetActivityEntityTypesErrors = { /** * Unauthorized */ 401: ErrorResponse; }; export type GetActivityEntityTypesError = GetActivityEntityTypesErrors[keyof GetActivityEntityTypesErrors]; export type GetActivityEntityTypesResponses = { /** * Entity types retrieved successfully */ 200: ActivityEntityTypesEnvelope; }; export type GetActivityEntityTypesResponse = GetActivityEntityTypesResponses[keyof GetActivityEntityTypesResponses]; export type GetActivityData = { body?: never; path: { /** * Activity identifier */ id: string; }; query?: never; url: '/api/v1/activities/{id}'; }; export type GetActivityErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Activity not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type GetActivityError = GetActivityErrors[keyof GetActivityErrors]; export type GetActivityResponses = { /** * Activity retrieved successfully */ 200: ActivityEnvelope; }; export type GetActivityResponse = GetActivityResponses[keyof GetActivityResponses]; export type GetPreferencesData = { body?: never; path?: never; query?: never; url: '/api/v1/preferences'; }; export type GetPreferencesErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error — failed to retrieve preferences */ 500: ErrorResponse; }; export type GetPreferencesError = GetPreferencesErrors[keyof GetPreferencesErrors]; export type GetPreferencesResponses = { /** * User preferences retrieved successfully */ 200: PreferencesResponse; }; export type GetPreferencesResponse = GetPreferencesResponses[keyof GetPreferencesResponses]; export type UpdatePreferencesData = { body: UpdatePreferencesRequest; path?: never; query?: never; url: '/api/v1/preferences'; }; export type UpdatePreferencesErrors = { /** * Invalid request body (malformed JSON) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error — preferences update failed */ 500: ErrorResponse; }; export type UpdatePreferencesError = UpdatePreferencesErrors[keyof UpdatePreferencesErrors]; export type UpdatePreferencesResponses = { /** * User preferences updated successfully */ 200: PreferencesResponse; }; export type UpdatePreferencesResponse = UpdatePreferencesResponses[keyof UpdatePreferencesResponses]; export type CompleteOnboardingData = { body?: never; path?: never; query?: never; url: '/api/v1/user/onboarding/complete'; }; export type CompleteOnboardingErrors = { /** * Unauthorized */ 401: ErrorResponse; /** * Internal server error — failed to mark onboarding completed or fetch user */ 500: ErrorResponse; }; export type CompleteOnboardingError = CompleteOnboardingErrors[keyof CompleteOnboardingErrors]; export type CompleteOnboardingResponses = { /** * Onboarding marked as completed — returns the updated user */ 200: User; }; export type CompleteOnboardingResponse = CompleteOnboardingResponses[keyof CompleteOnboardingResponses]; export type ListFeedItemRepliesData = { body?: never; path: { /** * Team identifier */ team_id: string; /** * Feed item identifier */ item_id: string; }; query?: { /** * Page number (default 1) */ page?: number; /** * Items per page (default 20, max 100) */ limit?: number; }; url: '/api/v1/{team_id}/feed-items/{item_id}/replies'; }; export type ListFeedItemRepliesErrors = { /** * Invalid item_id format */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — not a team member */ 403: ErrorResponse; /** * Feed item not found */ 404: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type ListFeedItemRepliesError = ListFeedItemRepliesErrors[keyof ListFeedItemRepliesErrors]; export type ListFeedItemRepliesResponses = { /** * Feed item replies retrieved successfully */ 200: FeedItemReplyListResponse; }; export type ListFeedItemRepliesResponse = ListFeedItemRepliesResponses[keyof ListFeedItemRepliesResponses]; export type CreateFeedItemReplyData = { body: CreateFeedItemReplyRequest; path: { /** * Team identifier */ team_id: string; /** * Feed item identifier */ item_id: string; }; query?: never; url: '/api/v1/{team_id}/feed-items/{item_id}/replies'; }; export type CreateFeedItemReplyErrors = { /** * Invalid item_id format, team_id not a valid UUID, invalid request body, or validation failed (content required/too long) */ 400: ErrorResponse; /** * Unauthorized */ 401: ErrorResponse; /** * Forbidden — insufficient team permissions */ 403: ErrorResponse; /** * Feed item not found */ 404: ErrorResponse; /** * Cannot reply to an archived feed item */ 422: ErrorResponse; /** * Internal server error */ 500: ErrorResponse; }; export type CreateFeedItemReplyError = CreateFeedItemReplyErrors[keyof CreateFeedItemReplyErrors]; export type CreateFeedItemReplyResponses = { /** * Feed item reply created successfully */ 201: FeedItemReply; }; export type CreateFeedItemReplyResponse = CreateFeedItemReplyResponses[keyof CreateFeedItemReplyResponses];