{
    "schemes": [],
    "swagger": "2.0",
    "info": {
        "description": "Machine-to-machine API for authorized admins (e.g. Katana) to provision and manage Ditto users and agent accounts on behalf of their own users. Authenticate every request with an admin key.",
        "title": "Ditto Admin API",
        "termsOfService": "https://heyditto.ai/terms",
        "contact": {
            "name": "HeyDitto Support",
            "email": "support@heyditto.ai"
        },
        "license": {
            "name": "Proprietary"
        },
        "version": "1.0"
    },
    "host": "",
    "basePath": "/api/admin/v1",
    "paths": {
        "/agent-accounts": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "List all agent accounts created by this app (paginated)",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "1-based page number",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "Page size (default 50)",
                        "name": "pageSize",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/pagination.Paginated-admin_AgentAccountSettings"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Creates an agent account. userID/userEmail are optional — omit both to provision an unowned agent claimable later via its token. subscribeGraphs pre-subscribes the agent to public foundation graphs (e.g. [\"@minos\"]) in the agent's own context. The apiKey and claimToken are returned ONCE. Send an Idempotency-Key header to make retries safe.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "Create an agent account for a user",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Optional idempotency key for safe retries",
                        "name": "Idempotency-Key",
                        "in": "header"
                    },
                    {
                        "description": "Owner + agent options",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.CreateAgentRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/admin.CreateAgentResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "409": {
                        "description": "Idempotency conflict / in progress",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/agent-accounts/{account_id}": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "Get a single agent account created by this app",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Agent account id",
                        "name": "account_id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.AgentAccountSettings"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "patch": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Patch an agent account's management settings. All fields optional. status: \"active\"/\"paused\" (resume/pause) or \"revoked\" (permanent; also revokes the MCP key). readonly toggles read-only mode. agentCaller renames the agent (its conversation-thread title follows). Read scope is managed via the readable-threads API, not here. Scoped to the app that created the account.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "Update an agent account's settings",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Agent account id",
                        "name": "account_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Settings to patch",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.UpdateAgentRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.AgentAccountSettings"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "409": {
                        "description": "Account is revoked",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/agent-accounts/{account_id}/link": {
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "Link an agent account to a user",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Agent account UUID",
                        "name": "account_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "User to link",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.LinkAgentRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.LinkAgentAccountResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/agent-accounts/{account_id}/readable-threads": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "List an agent account's readable threads",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Agent account id",
                        "name": "account_id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.AgentThreadsResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "put": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Replaces the agent's readable-thread allow-list. Selecting ≥1 thread restricts the agent to reading only those (read_scope \"restricted\"); an empty list restores \"all\" (an unscoped meta agent). Scoped to the app that created the account.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "Replace an agent account's readable threads",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Agent account id",
                        "name": "account_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Thread ids (session ids)",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.AgentThreadsRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.AgentThreadsResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "409": {
                        "description": "Account is revoked",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/agent-accounts/{account_id}/unlink": {
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "Unlink an agent account from its user",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Agent account UUID",
                        "name": "account_id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.LinkAgentAccountResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/consent-requests": {
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Mints a single-use, short-lived consent request and returns {consentURL, consentID, stateEcho}. Push the URL to your user; reconcile the outcome via the poll endpoint or the signed callback. Send an Idempotency-Key header to make retries safe.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "consent"
                ],
                "summary": "Create an OAuth consent request (returnable consent URL)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Optional idempotency key for safe retries",
                        "name": "Idempotency-Key",
                        "in": "header"
                    },
                    {
                        "description": "Requested scopes + optional state, callback uri",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.CreateConsentRequestRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.CreateConsentRequestResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/graphs": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "graphs"
                ],
                "summary": "List graphs provisioned by this app",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/admin.GraphResponse"
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Creates a private dedicated knowledge graph (kind='graph') owned by the app's developer and grouped under the calling app. Use it for an app's canonical/internal graphs (e.g. a documentation graph) that its agents can be pre-subscribed to. Private by default.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "graphs"
                ],
                "summary": "Provision a dedicated graph owned by this app",
                "parameters": [
                    {
                        "description": "Graph to create",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.CreateGraphRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/admin.GraphResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/users": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "users"
                ],
                "summary": "List users provisioned by this admin (paginated)",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "1-based page number",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "Page size (default 50)",
                        "name": "pageSize",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/pagination.Paginated-admin_AdminUserSummary"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Idempotently provision a Ditto user by email. A NEW email is provisioned freely (201). Re-calling for a user THIS app provisioned is idempotent (200, status \"already_provisioned\"). If the email belongs to a pre-existing Ditto user this app does NOT own, NO link is made and the response is 202 with a consentURL to hand to the user to approve the connection in their own Ditto account; once they approve, re-calling returns 200 (status \"connected\") with the user's uid.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "users"
                ],
                "summary": "Provision a user by email",
                "parameters": [
                    {
                        "description": "User to provision",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.UpsertUserRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Already provisioned by this app, or connected after consent",
                        "schema": {
                            "$ref": "#/definitions/admin.UpsertUserResponse"
                        }
                    },
                    "201": {
                        "description": "Newly provisioned",
                        "schema": {
                            "$ref": "#/definitions/admin.UpsertUserResponse"
                        }
                    },
                    "202": {
                        "description": "Existing user — consent required (consentURL returned)",
                        "schema": {
                            "$ref": "#/definitions/admin.UpsertUserResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "429": {
                        "description": "Too many consent requests",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/users/{user_id}": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Returns the user plus their agent accounts. {user_id} may be a Ditto uid or an email.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "users"
                ],
                "summary": "Get a provisioned user's state",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.UserStateResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "patch": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Update a user's name and/or external id. Only users this admin provisioned are editable.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "users"
                ],
                "summary": "Update a provisioned user",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Fields to update",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.UpdateUserRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.UserStateResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/users/{user_id}/agent-accounts": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "agents"
                ],
                "summary": "List a user's agent accounts (paginated)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "type": "integer",
                        "description": "1-based page number",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "Page size (default 50)",
                        "name": "pageSize",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/pagination.Paginated-admin_AgentAccountState"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/users/{user_id}/grant-requests": {
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Records pending consent requests the user approves in their app settings. Confers no access until approved.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "users"
                ],
                "summary": "Request data-sharing scopes from a user",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Requested scopes",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.RequestGrantsRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/users/{user_id}/keys": {
            "get": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "keys"
                ],
                "summary": "List a user's provider keys (status only)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.UserKeysResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "keys"
                ],
                "summary": "Set multiple provider keys (BYOK, batch)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Provider keys",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.SetUserKeysBatchRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.UserKeysResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        },
        "/users/{user_id}/keys/{provider}": {
            "put": {
                "security": [
                    {
                        "AdminKey": []
                    }
                ],
                "description": "Store a single provider key for a user. Mirrors the Ditto app's BYOK storage, so the key is enabled in the Ditto frontend too.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "keys"
                ],
                "summary": "Set one provider key (BYOK)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Ditto uid or email",
                        "name": "user_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Provider id (e.g. openrouter)",
                        "name": "provider",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Key value",
                        "name": "body",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/admin.SetUserKeyRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/admin.UserKeysResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/errs.Error"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "admin.AdminUserSummary": {
            "type": "object",
            "properties": {
                "email": {
                    "type": "string"
                },
                "firstName": {
                    "type": "string"
                },
                "lastName": {
                    "type": "string"
                },
                "userID": {
                    "type": "string"
                },
                "username": {
                    "type": "string"
                }
            }
        },
        "admin.AgentAccountSettings": {
            "type": "object",
            "properties": {
                "accountID": {
                    "type": "string"
                },
                "agentCaller": {
                    "type": "string"
                },
                "agentUserID": {
                    "type": "string"
                },
                "createdAt": {
                    "type": "string"
                },
                "pausedAt": {
                    "type": "string"
                },
                "readScope": {
                    "type": "string"
                },
                "readonly": {
                    "type": "boolean"
                },
                "revokedAt": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                }
            }
        },
        "admin.AgentAccountState": {
            "type": "object",
            "properties": {
                "accountID": {
                    "type": "string"
                },
                "agentCaller": {
                    "type": "string"
                },
                "agentUserID": {
                    "type": "string"
                },
                "apiKeyID": {
                    "type": "integer"
                },
                "claimedAt": {
                    "type": "string"
                },
                "claimedByUserID": {
                    "type": "string"
                },
                "createdAt": {
                    "type": "string"
                }
            }
        },
        "admin.AgentThreadsRequest": {
            "type": "object",
            "properties": {
                "threadIds": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "admin.AgentThreadsResponse": {
            "type": "object",
            "properties": {
                "readScope": {
                    "type": "string"
                },
                "threadIds": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "admin.CreateAgentRequest": {
            "type": "object",
            "properties": {
                "agentCaller": {
                    "type": "string"
                },
                "metadata": {
                    "type": "object",
                    "additionalProperties": {}
                },
                "readScope": {
                    "description": "ReadScope is \"all\" (unscoped meta agent — reads every thread; the default)\nor \"restricted\" (reads only its granted readable threads). Providing a\nnon-empty ReadableThreads forces \"restricted\".",
                    "type": "string"
                },
                "readableThreads": {
                    "description": "ReadableThreads scopes the agent to specific thread ids (session ids) at\ncreation. When non-empty the agent is created \"restricted\" and may read only\nthese threads; manage the set later via the readable-threads endpoints.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "readonly": {
                    "description": "Readonly provisions the agent in read-only mode (no writes via its key).",
                    "type": "boolean"
                },
                "subscribeAppGraphs": {
                    "description": "SubscribeAppGraphs pre-attaches the agent (read-only) to the app's OWN\ngraphs by graph app_id — e.g. a PRIVATE documentation graph the app\nprovisioned. Authorized because the same app key both creates the agent and\nowns the graph; grants a resource_acl viewer row so the agent reads it via\nthe ACL read path. Graphs not owned by this app are reported in failedGraphs.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "subscribeGraphs": {
                    "description": "SubscribeGraphs pre-subscribes the agent to public foundation knowledge\ngraphs by @username (e.g. [\"@minos\"]) so an app's agent works out of the box.\nThese subscriptions are keyed by the AGENT's own uid — they fold into the\nagent's own reads (app context) and NEVER the human owner's main Ditto app.\nBest-effort: graphs that aren't found / aren't public are reported in\nfailedGraphs and do not fail the request.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "userEmail": {
                    "type": "string"
                },
                "userID": {
                    "description": "UserID (Ditto uid) or UserEmail optionally identifies the owner. Omit BOTH\nto provision an UNOWNED agent that a user claims later via its claim token.",
                    "type": "string"
                }
            }
        },
        "admin.CreateAgentResponse": {
            "type": "object",
            "properties": {
                "accountID": {
                    "type": "string"
                },
                "agentCaller": {
                    "type": "string"
                },
                "agentUserID": {
                    "type": "string"
                },
                "apiKey": {
                    "type": "string"
                },
                "apiKeyID": {
                    "type": "integer"
                },
                "attachedAppGraphs": {
                    "description": "AttachedAppGraphs / FailedAppGraphs report the outcome of SubscribeAppGraphs\n(the app's OWN graphs, by app_id). Failed = not a graph this app owns.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "claimToken": {
                    "type": "string"
                },
                "claimURL": {
                    "type": "string"
                },
                "createdAt": {
                    "type": "string"
                },
                "failedAppGraphs": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "failedGraphs": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "ownerUserID": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                },
                "subscribedGraphs": {
                    "description": "SubscribedGraphs / FailedGraphs report the outcome of SubscribeGraphs\n(normalized @-stripped usernames). Failed = not found or not public.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "admin.CreateConsentRequestRequest": {
            "type": "object",
            "properties": {
                "callbackURI": {
                    "type": "string"
                },
                "requestedScopes": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "state": {
                    "type": "string"
                }
            }
        },
        "admin.CreateConsentRequestResponse": {
            "type": "object",
            "properties": {
                "consentID": {
                    "type": "string"
                },
                "consentURL": {
                    "type": "string"
                },
                "expiresAt": {
                    "type": "string"
                },
                "stateEcho": {
                    "type": "string"
                }
            }
        },
        "admin.CreateGraphRequest": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                }
            }
        },
        "admin.GraphResponse": {
            "type": "object",
            "properties": {
                "appID": {
                    "type": "string"
                },
                "kgID": {
                    "type": "string"
                },
                "kind": {
                    "type": "string"
                },
                "name": {
                    "type": "string"
                },
                "parentAppID": {
                    "type": "string"
                }
            }
        },
        "admin.LinkAgentAccountResponse": {
            "type": "object",
            "properties": {
                "accountID": {
                    "type": "string"
                },
                "agentUserID": {
                    "type": "string"
                },
                "claimedAt": {
                    "type": "string"
                },
                "claimedByUserID": {
                    "type": "string"
                },
                "status": {
                    "type": "string"
                }
            }
        },
        "admin.LinkAgentRequest": {
            "type": "object",
            "properties": {
                "userID": {
                    "type": "string"
                }
            }
        },
        "admin.RequestGrantsRequest": {
            "type": "object",
            "properties": {
                "scopes": {
                    "description": "Scopes the app wants the user to approve, e.g.\n[\"memories:read:main\",\"memories:write:app\"].",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "admin.SetUserKeyRequest": {
            "type": "object",
            "properties": {
                "enabled": {
                    "description": "Enabled defaults to true. Set false to store a fallback key the pipeline\nwon't use unless enabled.",
                    "type": "boolean"
                },
                "key": {
                    "type": "string"
                },
                "keyType": {
                    "type": "string"
                }
            }
        },
        "admin.SetUserKeysBatchRequest": {
            "type": "object",
            "properties": {
                "keys": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "enabled": {
                                "type": "boolean"
                            },
                            "key": {
                                "type": "string"
                            },
                            "keyType": {
                                "type": "string"
                            },
                            "provider": {
                                "type": "string"
                            }
                        }
                    }
                }
            }
        },
        "admin.UpdateAgentRequest": {
            "type": "object",
            "properties": {
                "agentCaller": {
                    "description": "AgentCaller updates the agent's friendly display name. The rename follows\nthrough to the agent's conversation-thread title for the claiming user.",
                    "type": "string"
                },
                "readonly": {
                    "description": "Readonly toggles whether the agent may only READ (no writes) via its key.",
                    "type": "boolean"
                },
                "status": {
                    "description": "Status moves the account between \"active\" and \"paused\" (pause/resume), or\n\"revoked\" to permanently disable it (also revokes its MCP key). A revoked\naccount cannot be modified further.",
                    "type": "string"
                }
            }
        },
        "admin.UpdateUserRequest": {
            "type": "object",
            "properties": {
                "firstName": {
                    "type": "string"
                },
                "lastName": {
                    "type": "string"
                },
                "username": {
                    "description": "Username sets the user's public handle. Must be unique (case-insensitive)\n— a collision returns 409.",
                    "type": "string"
                }
            }
        },
        "admin.UpsertUserRequest": {
            "type": "object",
            "properties": {
                "email": {
                    "type": "string"
                },
                "firstName": {
                    "type": "string"
                },
                "lastName": {
                    "type": "string"
                },
                "requestMainScopes": {
                    "description": "RequestMainScopes are the MAIN-KG scopes the app wants on the user's\npersonal knowledge graph (their existing Ditto memories \u0026 preferences).\nThese are OPT-IN: they are added to the connection consent for a\nPRE-EXISTING Ditto user, the user approves them on the consent screen, and\nthey are NEVER auto-granted. Ignored for a brand-new provisioned shell user\n(no main-KG history to share). The app's OWN isolated app-KG scopes\n(memories:{read,create,update,delete,archive}:app) are ALWAYS auto-granted\non connection and must NOT be listed here — only main-KG scopes are valid;\nany other (incl. app-KG) scope is rejected with 400.\n\nValid values (all end in \":main\"):\n  - memories:read:main    — read the user's main memories \u0026 preferences\n  - memories:create:main  — add memories to the user's main graph\n  - memories:update:main  — modify existing main memories\n  - memories:delete:main  — delete main memories\n  - memories:archive:main — archive main memories\nread is low-sensitivity; update/delete/archive are high-trust and the\nconsent screen flags them accordingly.",
                    "type": "array",
                    "items": {
                        "type": "string",
                        "enum": [
                            "memories:read:main",
                            "memories:create:main",
                            "memories:update:main",
                            "memories:delete:main",
                            "memories:archive:main"
                        ]
                    }
                },
                "username": {
                    "description": "Username sets the user's public handle. Only applied when the user is\nnewly provisioned; for an existing user use PATCH. Must be unique\n(case-insensitive) — a collision returns 409.",
                    "type": "string"
                }
            }
        },
        "admin.UpsertUserResponse": {
            "type": "object",
            "properties": {
                "consentID": {
                    "type": "string"
                },
                "consentURL": {
                    "description": "Set only when Status == \"consent_required\": the URL to hand to the user to\napprove the connection in their own Ditto account, the consent id to\nreconcile against, and its expiry.",
                    "type": "string"
                },
                "created": {
                    "type": "boolean"
                },
                "email": {
                    "type": "string"
                },
                "expiresAt": {
                    "type": "string"
                },
                "status": {
                    "description": "Status: \"provisioned\" (newly created by this admin), \"already_provisioned\"\n(this admin created it earlier), or \"consent_required\" (a pre-existing Ditto\nuser this admin does not own — no link/grant was made; the user must approve\nthe connection via consentURL before the app appears in their account).",
                    "type": "string"
                },
                "userID": {
                    "type": "string"
                },
                "username": {
                    "type": "string"
                }
            }
        },
        "admin.UserKeyStatus": {
            "type": "object",
            "properties": {
                "configured": {
                    "type": "boolean"
                },
                "enabled": {
                    "type": "boolean"
                },
                "keyHint": {
                    "type": "string"
                },
                "keyType": {
                    "type": "string"
                },
                "provider": {
                    "type": "string"
                }
            }
        },
        "admin.UserKeysResponse": {
            "type": "object",
            "properties": {
                "keys": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/admin.UserKeyStatus"
                    }
                }
            }
        },
        "admin.UserStateResponse": {
            "type": "object",
            "properties": {
                "agentAccounts": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/admin.AgentAccountState"
                    }
                },
                "email": {
                    "type": "string"
                },
                "firstName": {
                    "type": "string"
                },
                "lastName": {
                    "type": "string"
                },
                "provisionedBy": {
                    "type": "string"
                },
                "userID": {
                    "type": "string"
                },
                "username": {
                    "type": "string"
                }
            }
        },
        "errs.Error": {
            "type": "object",
            "properties": {
                "message": {
                    "type": "string"
                },
                "status": {
                    "type": "integer"
                }
            }
        },
        "pagination.Paginated-admin_AdminUserSummary": {
            "type": "object",
            "properties": {
                "items": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/admin.AdminUserSummary"
                    }
                },
                "nextPage": {
                    "type": "integer"
                },
                "page": {
                    "type": "integer"
                },
                "pageSize": {
                    "type": "integer"
                },
                "prevPage": {
                    "type": "integer"
                }
            }
        },
        "pagination.Paginated-admin_AgentAccountSettings": {
            "type": "object",
            "properties": {
                "items": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/admin.AgentAccountSettings"
                    }
                },
                "nextPage": {
                    "type": "integer"
                },
                "page": {
                    "type": "integer"
                },
                "pageSize": {
                    "type": "integer"
                },
                "prevPage": {
                    "type": "integer"
                }
            }
        },
        "pagination.Paginated-admin_AgentAccountState": {
            "type": "object",
            "properties": {
                "items": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/admin.AgentAccountState"
                    }
                },
                "nextPage": {
                    "type": "integer"
                },
                "page": {
                    "type": "integer"
                },
                "pageSize": {
                    "type": "integer"
                },
                "prevPage": {
                    "type": "integer"
                }
            }
        }
    },
    "securityDefinitions": {
        "AdminKey": {
            "description": "Admin API key in the Authorization header — paste the raw key (e.g. `ditto_admin_\u003cadmin\u003e_\u003csecret\u003e`); a `Bearer ` prefix is optional. Mint one in the Ditto app under Settings → Admin.",
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
}