openapi: 3.1.0
info:
  title: Configure API
  version: 2026-04-29
  summary: Canonical public API for Configure developer and agent integrations.
  description: |
    Configure is the identity layer for AI agents. This OpenAPI document covers
    the public SDK-backed developer/runtime HTTP endpoints: profiles, memories,
    Configure File System (CFS) file operations, and tools.

    CFS is Configure's path-addressed storage layer for identity JSON, profile
    documents, connected-tool state and cached artifacts, and per-agent memories.
    The Memory Profile is the semantic developer-facing view composed from CFS.
    Endpoint names follow developer intent rather than the storage layer touched
    internally.

    Identity modes:
    - Federated users use X-API-Key plus an agent-scoped Bearer token from hosted Configure.auth().
    - Unlinked users use a server-side sk_ key plus X-User-Id. This creates a developer-scoped profile that can be linked later with Configure.auth({ externalId }).

    The API creates or updates unlinked developer-scoped profiles only.
    Federated phone-linked users are created or linked through hosted Configure
    auth components after phone verification.

    Dashboard, admin, hosted-surface, and migration endpoints are outside this
    public SDK-backed API contract unless separately documented.
servers:
  - url: https://api.configure.dev
    description: Production
tags:
  - name: Profile
  - name: Raw Profile Files
  - name: Raw Agent Files
  - name: Tools
security:
  - ApiKeyAuth: []
paths:
  /v1/profile:
    get:
      tags: [Profile]
      summary: Read composed profile
      description: Reads a composed Memory Profile. Use Bearer auth for federated users or sk_ plus X-User-Id for unlinked developer-scoped users.
      security:
        - ApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdQuery"
        - name: path
          in: query
          schema:
            type: string
          description: Dot-path into the composed profile.
        - name: sections
          in: query
          schema:
            type: string
          description: Comma-separated subset of identity, preferences, integrations, agents, summary.
        - name: format
          in: query
          schema:
            type: string
            enum: [manifest]
          description: Use manifest for a lightweight shape/counts response.
      responses:
        "200":
          description: Composed profile or manifest.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "403":
          $ref: "#/components/responses/Forbidden"

  /v1/profile/memories:
    get:
      tags: [Profile]
      summary: Query memories
      security:
        - ApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdQuery"
        - name: agent
          in: query
          schema:
            type: string
        - name: agents
          in: query
          schema:
            type: string
          description: Comma-separated agent names.
        - name: from
          in: query
          schema:
            type: string
            format: date
        - name: to
          in: query
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Memory query results.
          content:
            application/json:
              schema:
                type: object
                properties:
                  memories:
                    type: array
                    items:
                      $ref: "#/components/schemas/MemoryEntry"

  /v1/profile/remember:
    post:
      tags: [Profile]
      summary: Save one fact
      description: Requires a secret key. Appends the fact under /agents/{resolved-agent}/memories/{date}.md.
      security:
        - SecretApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RememberRequest"
      responses:
        "200":
          description: Fact saved.
          content:
            application/json:
              schema:
                type: object
                properties:
                  saved:
                    type: boolean
                  app:
                    type: string
                  fact:
                    type: string
        "403":
          $ref: "#/components/responses/Forbidden"

  /v1/profile/ingest:
    post:
      tags: [Profile]
      summary: Ingest text, messages, or batch users
      description: Requires a secret key. Single-user mode also requires Bearer auth or X-User-Id. Batch mode uses users[] and creates or updates unlinked profiles without per-user auth.
      security:
        - SecretApiKeyAuth: []
        - SecretApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/IngestRequest"
      responses:
        "200":
          description: Completed ingest.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "202":
          description: Async ingest accepted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: processing

  /v1/profile/documents:
    get:
      tags: [Profile]
      summary: Read generated profile documents
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdQuery"
      responses:
        "200":
          description: Generated profile documents.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true

  /v1/profile/documents/generate:
    post:
      tags: [Profile]
      summary: Regenerate profile documents
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [user_id]
              properties:
                user_id:
                  type: string
                documents:
                  type: array
                  items:
                    type: string
                    enum: [user.md, soul.md, preferences.md, context.md, all]
      responses:
        "200":
          description: Generation result.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true

  /v1/profile/{userId}:
    get:
      tags: [Raw Profile Files]
      summary: List profile CFS subtree
      security:
        - ApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdPath"
        - $ref: "#/components/parameters/CfsPathQuery"
        - $ref: "#/components/parameters/DepthQuery"
        - $ref: "#/components/parameters/LimitQuery"
      responses:
        "200":
          $ref: "#/components/responses/CfsList"
    delete:
      tags: [Raw Profile Files]
      summary: Delete profile CFS node
      description: Requires a secret key. Federated users are namespace-fenced to /agents/{resolved-agent}; unlinked developer-scoped profiles may also manage root profile paths.
      security:
        - SecretApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdPath"
        - $ref: "#/components/parameters/CfsPathQueryRequired"
      responses:
        "200":
          description: Delete result.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true

  /v1/profile/{userId}/read:
    get:
      tags: [Raw Profile Files]
      summary: Read profile CFS node
      security:
        - ApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdPath"
        - $ref: "#/components/parameters/CfsPathQueryRequired"
      responses:
        "200":
          description: CFS node, null if missing or filtered.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/CfsNode"
                  - type: "null"

  /v1/profile/{userId}/search:
    get:
      tags: [Raw Profile Files]
      summary: Search profile CFS
      security:
        - ApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdPath"
        - $ref: "#/components/parameters/SearchQuery"
        - $ref: "#/components/parameters/ScopeQuery"
        - $ref: "#/components/parameters/SearchLimitQuery"
        - $ref: "#/components/parameters/FilesOnlyQuery"
      responses:
        "200":
          $ref: "#/components/responses/CfsSearch"

  /v1/profile/{userId}/write:
    put:
      tags: [Raw Profile Files]
      summary: Write profile CFS node
      description: Requires a secret key. Federated users are namespace-fenced to /agents/{resolved-agent}; unlinked developer-scoped profiles may also manage root profile paths.
      security:
        - SecretApiKeyAuth: []
          BearerAuth: []
        - SecretApiKeyAuth: []
          ExternalUserId: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/UserIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CfsWriteRequest"
      responses:
        "200":
          description: Write result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CfsWriteResult"

  /v1/self:
    get:
      tags: [Raw Agent Files]
      summary: List calling agent CFS
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/CfsPathQuery"
        - $ref: "#/components/parameters/DepthQuery"
        - $ref: "#/components/parameters/LimitQuery"
      responses:
        "200":
          $ref: "#/components/responses/CfsList"
    delete:
      tags: [Raw Agent Files]
      summary: Delete calling agent CFS node
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/CfsPathQueryRequired"
      responses:
        "200":
          description: Delete result.

  /v1/self/read:
    get:
      tags: [Raw Agent Files]
      summary: Read calling agent CFS node
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/CfsPathQueryRequired"
      responses:
        "200":
          description: CFS node.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CfsNode"

  /v1/self/search:
    get:
      tags: [Raw Agent Files]
      summary: Search calling agent CFS
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/SearchQuery"
        - $ref: "#/components/parameters/ScopeQuery"
        - $ref: "#/components/parameters/SearchLimitQuery"
        - $ref: "#/components/parameters/FilesOnlyQuery"
      responses:
        "200":
          $ref: "#/components/responses/CfsSearch"

  /v1/self/write:
    put:
      tags: [Raw Agent Files]
      summary: Write calling agent CFS node
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CfsWriteRequest"
      responses:
        "200":
          description: Write result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CfsWriteResult"

  /v1/agent/{name}:
    get:
      tags: [Raw Agent Files]
      summary: List peer agent CFS
      description: Read-only and permission-gated by the target agent's /permissions node.
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/AgentNamePath"
        - $ref: "#/components/parameters/CfsPathQuery"
        - $ref: "#/components/parameters/DepthQuery"
        - $ref: "#/components/parameters/LimitQuery"
      responses:
        "200":
          $ref: "#/components/responses/CfsList"

  /v1/agent/{name}/read:
    get:
      tags: [Raw Agent Files]
      summary: Read peer agent CFS node
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/AgentNamePath"
        - $ref: "#/components/parameters/CfsPathQueryRequired"
      responses:
        "200":
          description: CFS node, null if missing or filtered.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/CfsNode"
                  - type: "null"

  /v1/agent/{name}/search:
    get:
      tags: [Raw Agent Files]
      summary: Search peer agent CFS
      security:
        - SecretApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/AgentNamePath"
        - $ref: "#/components/parameters/SearchQuery"
        - $ref: "#/components/parameters/ScopeQuery"
        - $ref: "#/components/parameters/SearchLimitQuery"
        - $ref: "#/components/parameters/FilesOnlyQuery"
      responses:
        "200":
          $ref: "#/components/responses/CfsSearch"

  /v1/tools:
    get:
      tags: [Tools]
      summary: List connected tool status
      description: Requires a federated approved user. Unlinked X-User-Id users cannot use connected tools until linked.
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      responses:
        "200":
          description: Available tools.
          content:
            application/json:
              schema:
                type: object
                properties:
                  tools:
                    type: array
                    items:
                      type: object
                      additionalProperties: true

  /v1/tools/{tool}/connect:
    post:
      tags: [Tools]
      summary: Start tool OAuth
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/ToolPath"
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                callbackUrl:
                  type: string
                  format: uri
                returnUrl:
                  type: string
                  format: uri
                forceNew:
                  type: boolean
      responses:
        "200":
          description: OAuth URL or existing connection.

  /v1/tools/{tool}/confirm:
    post:
      tags: [Tools]
      summary: Confirm tool OAuth
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/ToolPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [connectionRequestId]
              properties:
                connectionRequestId:
                  type: string
      responses:
        "200":
          description: Connection result.

  /v1/tools/{tool}/sync:
    post:
      tags: [Tools]
      summary: Sync one tool
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/ToolPath"
      responses:
        "200":
          description: Sync result.

  /v1/tools/{tool}:
    delete:
      tags: [Tools]
      summary: Disconnect one tool
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
        - $ref: "#/components/parameters/ToolPath"
      responses:
        "200":
          description: Disconnect result.

  /v1/tools/disconnect-all:
    post:
      tags: [Tools]
      summary: Disconnect all tools and reset profile CFS
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      responses:
        "200":
          description: Disconnect result.

  /v1/tools/sync:
    post:
      tags: [Tools]
      summary: Sync selected connected tools
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SyncRequest"
      responses:
        "200":
          description: Sync result.

  /v1/tools/gmail/messages/search:
    post:
      tags: [Tools]
      summary: Search Gmail
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SearchRequest"
      responses:
        "200":
          description: Email search results.

  /v1/tools/calendar/events/query:
    post:
      tags: [Tools]
      summary: Read calendar events
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CalendarRequest"
      responses:
        "200":
          description: Calendar results.

  /v1/tools/drive/files/search:
    post:
      tags: [Tools]
      summary: Search Drive files
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SearchRequest"
      responses:
        "200":
          description: File search results.

  /v1/tools/notion/pages/search:
    post:
      tags: [Tools]
      summary: Search Notion
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SearchRequest"
      responses:
        "200":
          description: Notion search results.

  /v1/tools/web/search:
    post:
      tags: [Tools]
      summary: Search web
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SearchRequest"
      responses:
        "200":
          description: Web search results.

  /v1/tools/web/fetch:
    post:
      tags: [Tools]
      summary: Fetch URL content
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FetchUrlRequest"
      responses:
        "200":
          description: URL content result.

  /v1/tools/calendar/events:
    post:
      tags: [Tools]
      summary: Create calendar event
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateEventRequest"
      responses:
        "200":
          description: Event creation result.

  /v1/tools/gmail/messages/send:
    post:
      tags: [Tools]
      summary: Send email
      security:
        - ApiKeyAuth: []
          BearerAuth: []
      parameters:
        - $ref: "#/components/parameters/AgentHeader"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendEmailRequest"
      responses:
        "200":
          description: Send result.

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Configure API key. Use sk_ on servers. pk_ is browser-safe but restricted.
    SecretApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Server-side Configure secret key, prefix sk_.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Agent-scoped user token from hosted Configure.auth().
    ExternalUserId:
      type: apiKey
      in: header
      name: X-User-Id
      description: Stable external user ID for unlinked developer-scoped profiles. Requires sk_.
  parameters:
    AgentHeader:
      name: X-Agent
      in: header
      required: false
      schema:
        $ref: "#/components/schemas/AgentName"
      description: Required when the API key's developer account owns more than one active agent.
    UserIdQuery:
      name: user_id
      in: query
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 255
    UserIdPath:
      name: userId
      in: path
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 255
    AgentNamePath:
      name: name
      in: path
      required: true
      schema:
        $ref: "#/components/schemas/AgentName"
    ToolPath:
      name: tool
      in: path
      required: true
      schema:
        $ref: "#/components/schemas/ToolName"
    CfsPathQuery:
      name: path
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/CfsPath"
      description: Defaults to /.
    CfsPathQueryRequired:
      name: path
      in: query
      required: true
      schema:
        $ref: "#/components/schemas/CfsPath"
    DepthQuery:
      name: depth
      in: query
      required: false
      schema:
        type: integer
        default: 1
        minimum: 1
    LimitQuery:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        default: 100
        maximum: 500
    SearchQuery:
      name: query
      in: query
      required: true
      schema:
        type: string
        minLength: 1
    ScopeQuery:
      name: scope
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/CfsPath"
      description: Defaults to /.
    SearchLimitQuery:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        default: 10
        maximum: 50
    FilesOnlyQuery:
      name: files_only
      in: query
      required: false
      schema:
        type: boolean
        default: false
  schemas:
    AgentName:
      type: string
      minLength: 2
      maxLength: 63
      pattern: "^[a-z0-9][a-z0-9-]*[a-z0-9]$"
      example: atlas
    ToolName:
      type: string
      enum: [gmail, calendar, drive, notion]
    MemoryEntry:
      type: object
      properties:
        agent:
          type: string
        date:
          type: string
        content:
          type: string
        source:
          type: string
    RememberRequest:
      oneOf:
        - type: object
          required: [user_id, fact]
          properties:
            user_id:
              type: string
              minLength: 1
              maxLength: 255
            fact:
              type: string
              minLength: 1
              maxLength: 10000
        - type: object
          required: [user_id, key, value]
          properties:
            user_id:
              type: string
              minLength: 1
              maxLength: 255
            key:
              type: string
              maxLength: 100
            value:
              type: string
              maxLength: 10000
    ConversationMessage:
      type: object
      required: [role, content]
      properties:
        role:
          type: string
          enum: [user, assistant]
        content:
          type: string
          minLength: 1
    IngestRequest:
      oneOf:
        - type: object
          required: [user_id]
          anyOf:
            - required: [messages]
            - required: [text]
          properties:
            user_id:
              type: string
              minLength: 1
              maxLength: 255
            messages:
              type: array
              minItems: 1
              items:
                $ref: "#/components/schemas/ConversationMessage"
            text:
              type: string
              minLength: 1
              maxLength: 500000
            memory_criteria:
              type: string
              maxLength: 2000
            sync:
              type: boolean
              default: false
        - type: object
          required: [users]
          properties:
            users:
              type: array
              minItems: 1
              maxItems: 50
              items:
                $ref: "#/components/schemas/IngestUser"
            memory_criteria:
              type: string
              maxLength: 2000
            sync:
              type: boolean
              default: false
    IngestUser:
      type: object
      required: [user_id]
      properties:
        user_id:
          type: string
          minLength: 1
          maxLength: 255
        messages:
          type: array
          items:
            $ref: "#/components/schemas/ConversationMessage"
        text:
          type: string
          minLength: 1
          maxLength: 500000
        conversations:
          type: array
          minItems: 1
          maxItems: 20
          items:
            type: object
            required: [messages]
            properties:
              messages:
                type: array
                minItems: 1
                maxItems: 100
                items:
                  $ref: "#/components/schemas/ConversationMessage"
    CfsPath:
      type: string
      minLength: 1
      maxLength: 500
      pattern: "^/[a-zA-Z0-9._/-]*$"
      example: /identity.json
    CfsNode:
      type: object
      properties:
        path:
          type: string
        content:
          type: string
        type:
          type: string
          enum: [json, markdown]
        updated_at:
          type: string
          format: date-time
      additionalProperties: true
    CfsEntry:
      type: object
      properties:
        path:
          type: string
        type:
          type: string
        updated_at:
          type: string
          format: date-time
      additionalProperties: true
    CfsWriteRequest:
      type: object
      required: [path, content]
      properties:
        path:
          $ref: "#/components/schemas/CfsPath"
        content:
          type: string
          maxLength: 1000000
        type:
          type: string
          enum: [json, markdown]
          default: markdown
        mode:
          type: string
          enum: [overwrite, append, merge]
          default: overwrite
    CfsWriteResult:
      type: object
      properties:
        path:
          type: string
        version:
          type: integer
      additionalProperties: true
    SearchRequest:
      type: object
      required: [user_id, query]
      properties:
        user_id:
          type: string
        query:
          type: string
          minLength: 1
        max_results:
          type: integer
          default: 10
          minimum: 1
          maximum: 50
    CalendarRequest:
      type: object
      required: [user_id]
      properties:
        user_id:
          type: string
        range:
          type: string
          enum: [today, tomorrow, week, month]
          default: week
    FetchUrlRequest:
      type: object
      required: [user_id, url]
      properties:
        user_id:
          type: string
        url:
          type: string
          format: uri
        max_length:
          type: integer
          minimum: 100
          maximum: 100000
    SyncRequest:
      type: object
      required: [user_id]
      properties:
        user_id:
          type: string
        tools:
          type: array
          items:
            $ref: "#/components/schemas/ToolName"
    CreateEventRequest:
      type: object
      required: [user_id, title, start_time, end_time]
      properties:
        user_id:
          type: string
        title:
          type: string
          minLength: 1
          maxLength: 500
        start_time:
          type: string
        end_time:
          type: string
        description:
          type: string
          maxLength: 5000
        location:
          type: string
          maxLength: 500
    SendEmailRequest:
      type: object
      required: [user_id, to, subject, body]
      properties:
        user_id:
          type: string
        to:
          type: string
          format: email
        subject:
          type: string
          minLength: 1
          maxLength: 500
        body:
          type: string
          minLength: 1
          maxLength: 50000
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
            code:
              type: string
            message:
              type: string
            param:
              type:
                - string
                - "null"
            retryable:
              type: boolean
        request_id:
          type: string
  responses:
    Forbidden:
      description: Forbidden. Common causes include secret_key_required, token_wrong_type, approval_required, or access_denied.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    CfsList:
      description: CFS listing.
      content:
        application/json:
          schema:
            type: object
            properties:
              entries:
                type: array
                items:
                  $ref: "#/components/schemas/CfsEntry"
              count:
                type: integer
    CfsSearch:
      description: CFS search results.
      content:
        application/json:
          schema:
            type: object
            properties:
              results:
                type: array
                items:
                  $ref: "#/components/schemas/CfsEntry"
              count:
                type: integer
