{
  "openapi": "3.0.3",
  "info": {
    "title": "di3 API",
    "description": "API for di3 canvases. Authenticate with `Authorization: Bearer <your_api_key>`.",
    "license": {
      "name": ""
    },
    "version": "1.0.0"
  },
  "paths": {
    "/api/canvases": {
      "get": {
        "tags": [
          "api::canvas"
        ],
        "summary": "List all canvases accessible to the authenticated user",
        "operationId": "list_all_canvases",
        "responses": {
          "200": {
            "description": "List of canvases",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CanvasListItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "cookie_auth": []
          },
          {
            "api_key": []
          }
        ]
      },
      "post": {
        "tags": [
          "api::canvas"
        ],
        "summary": "Create a new canvas",
        "operationId": "create_canvas_flat",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {}
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Canvas created",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "cookie_auth": []
          },
          {
            "api_key": []
          }
        ]
      }
    },
    "/api/canvases/{id}": {
      "get": {
        "tags": [
          "api::canvas"
        ],
        "summary": "Get a single canvas by ID",
        "operationId": "get_canvas",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Canvas ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Canvas content"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "cookie_auth": []
          },
          {
            "api_key": []
          }
        ]
      },
      "put": {
        "tags": [
          "api::canvas"
        ],
        "summary": "Update a canvas",
        "operationId": "update_canvas",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Canvas ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {}
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Canvas updated. `warnings` carries non-fatal guidance on the saved graph - the update already succeeded, but acting on it produces a better diagram."
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "cookie_auth": []
          },
          {
            "api_key": []
          }
        ]
      },
      "delete": {
        "tags": [
          "api::canvas"
        ],
        "summary": "Delete a canvas",
        "operationId": "delete_canvas",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Canvas ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Canvas deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          }
        },
        "security": [
          {
            "cookie_auth": []
          },
          {
            "api_key": []
          }
        ]
      }
    },
    "/api/user/api-keys": {
      "get": {
        "tags": [
          "api::api_keys"
        ],
        "summary": "List all API keys for the current user",
        "operationId": "list_api_keys",
        "responses": {
          "200": {
            "description": "List of API keys (raw key values are never returned here)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApiKeyResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "cookie_auth": []
          }
        ]
      },
      "post": {
        "tags": [
          "api::api_keys"
        ],
        "summary": "Create a new API key (the raw key is returned once - store it securely)",
        "operationId": "create_api_key",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "API key created - raw key shown only once",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateApiKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "security": [
          {
            "cookie_auth": []
          }
        ]
      }
    },
    "/api/user/api-keys/{id}": {
      "delete": {
        "tags": [
          "api::api_keys"
        ],
        "summary": "Revoke an API key",
        "operationId": "revoke_api_key",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "API key ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Key revoked"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Key not found or not owned by you"
          }
        },
        "security": [
          {
            "cookie_auth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ApiKeyResponse": {
        "type": "object",
        "required": [
          "id",
          "name",
          "key_prefix",
          "expires_at",
          "created_at"
        ],
        "properties": {
          "canvasId": {
            "type": "string",
            "nullable": true
          },
          "canvasName": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          },
          "expires_at": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "key_prefix": {
            "type": "string",
            "description": "First 12 characters of the key, for identification only"
          },
          "last_used_at": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string"
          }
        }
      },
      "CanvasListItem": {
        "type": "object",
        "required": [
          "id",
          "name",
          "nodes_count",
          "edges_count",
          "canvasType"
        ],
        "properties": {
          "canvasType": {
            "type": "string"
          },
          "edges_count": {
            "type": "integer",
            "format": "int64"
          },
          "id": {
            "type": "string"
          },
          "is_shared": {
            "type": "boolean",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "nodes_count": {
            "type": "integer",
            "format": "int64"
          },
          "vaultId": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CreateApiKeyRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "canvasId": {
            "type": "string",
            "description": "Restrict the key to one canvas (\"Agent\" key) - the caller must own it.",
            "nullable": true
          },
          "expiresInDays": {
            "type": "integer",
            "format": "int64",
            "description": "Override the default expiry (1 day). Clamped to 1..=365.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "description": "A descriptive name for this key (e.g. \"Claude AI access\")"
          }
        }
      },
      "CreateApiKeyResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiKeyResponse"
          },
          {
            "type": "object",
            "required": [
              "key"
            ],
            "properties": {
              "key": {
                "type": "string",
                "description": "Full API key value - shown only once, store it securely"
              }
            }
          }
        ]
      }
    },
    "securitySchemes": {
      "api_key": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "d3k_<token>"
      },
      "cookie_auth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "token"
      }
    }
  },
  "security": [
    {
      "api_key": []
    },
    {
      "cookie_auth": []
    }
  ]
}