{
  "openapi": "3.1.0",
  "info": {
    "title": "Folder API",
    "version": "1.0.0",
    "description": "Public file-storage API for agent workspaces and application backends. Folder is storage, not a database or an S3-compatible endpoint."
  },
  "servers": [{ "url": "https://www.folder.md/api/v1", "description": "Production" }],
  "externalDocs": { "description": "Folder Developer Docs", "url": "https://www.folder.md/docs" },
  "tags": [
    { "name": "Folders" },
    { "name": "Files" },
    { "name": "Direct uploads" },
    { "name": "Subfolders" },
    { "name": "API keys" },
    { "name": "Webhooks" },
    { "name": "Agent workflows" }
  ],
  "paths": {
    "/folders": {
      "get": { "tags": ["Folders"], "summary": "List accessible Folders", "security": [{ "bearerAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/Success" }, "401": { "$ref": "#/components/responses/Unauthorized" } } },
      "post": { "tags": ["Folders"], "summary": "Create a Folder", "description": "Requires admin permission.", "security": [{ "bearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateFolder" } } } }, "responses": { "201": { "$ref": "#/components/responses/Success" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/folders/{folderId}": {
      "parameters": [{ "$ref": "#/components/parameters/FolderId" }],
      "get": { "tags": ["Folders"], "summary": "Get Folder metadata", "security": [{ "bearerAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/Success" }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "patch": { "tags": ["Folders"], "summary": "Update Folder metadata", "security": [{ "bearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "maxLength": 100 }, "description": { "type": "string" } } } } } }, "responses": { "200": { "$ref": "#/components/responses/Success" }, "403": { "$ref": "#/components/responses/Forbidden" } } },
      "delete": { "tags": ["Folders"], "summary": "Delete a Folder and its contents", "security": [{ "bearerAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/Success" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/folders/{folderId}/tree": {
      "get": { "tags": ["Folders"], "summary": "Get the full Folder tree", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/activity": {
      "get": { "tags": ["Folders"], "summary": "List recent Folder activity", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "name": "path", "in": "query", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "schema": { "type": "integer" } }], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/files": {
      "get": { "tags": ["Files"], "summary": "List files", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "name": "path", "in": "query", "schema": { "type": "string" } }], "responses": { "200": { "$ref": "#/components/responses/Success" } } },
      "post": { "tags": ["Files"], "summary": "Upload a file through the Folder API", "description": "Accepts multipart form data or a raw body with X-File-Path. Maximum 100 MB. Files use Folder application-layer encryption.", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "name": "X-File-Path", "in": "header", "required": false, "schema": { "type": "string" }, "description": "Required for raw-body uploads." }, { "name": "X-File-Sha256", "in": "header", "required": false, "schema": { "type": "string" } }], "requestBody": { "required": true, "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } }, "multipart/form-data": { "schema": { "type": "object", "required": ["file"], "properties": { "file": { "type": "string", "format": "binary" }, "path": { "type": "string" }, "tags": { "type": "string" }, "sha256": { "type": "string" } } } } } }, "responses": { "201": { "$ref": "#/components/responses/Success" }, "409": { "$ref": "#/components/responses/Conflict" }, "429": { "$ref": "#/components/responses/RateLimited" } } }
    },
    "/folders/{folderId}/files/{fileId}": {
      "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "$ref": "#/components/parameters/FileId" }],
      "get": { "tags": ["Files"], "summary": "Get file metadata or download content", "security": [{ "bearerAuth": [] }], "parameters": [{ "name": "download", "in": "query", "schema": { "type": "boolean", "default": false } }], "responses": { "200": { "$ref": "#/components/responses/Success" }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "put": { "tags": ["Files"], "summary": "Replace file contents", "description": "Explicitly replaces content and increments the version. Maximum 100 MB.", "security": [{ "bearerAuth": [] }], "requestBody": { "required": true, "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } }, "application/json": { "schema": { "type": "object", "required": ["content"], "properties": { "content": { "type": "string" }, "mime_type": { "type": "string" } } } } } }, "responses": { "200": { "$ref": "#/components/responses/Success" }, "403": { "$ref": "#/components/responses/Forbidden" } } },
      "delete": { "tags": ["Files"], "summary": "Delete a file", "security": [{ "bearerAuth": [] }], "responses": { "200": { "$ref": "#/components/responses/Success" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/folders/{folderId}/files/{fileId}/activity": {
      "get": { "tags": ["Files"], "summary": "List recent file activity", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "$ref": "#/components/parameters/FileId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/direct-uploads": {
      "post": { "tags": ["Direct uploads"], "summary": "Initiate a direct single-part upload", "description": "Returns a 15-minute presigned R2 PUT URL and completion token. The Folder quota still applies. Direct uploads use R2-managed AES-256 at rest and bypass Folder application-layer encryption. Multipart and resumable uploads are not active.", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectUploadRequest" } } } }, "responses": { "201": { "description": "Upload URL created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectUploadResponse" } } } }, "409": { "$ref": "#/components/responses/Conflict" }, "429": { "$ref": "#/components/responses/RateLimited" } } }
    },
    "/folders/{folderId}/direct-uploads/complete": {
      "post": { "tags": ["Direct uploads"], "summary": "Complete a direct upload", "description": "Verifies the uploaded object and declared size, creates Folder metadata, and emits file.created.", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["token"], "properties": { "token": { "type": "string" } } } } } }, "responses": { "201": { "$ref": "#/components/responses/Success" }, "409": { "$ref": "#/components/responses/Conflict" } } }
    },
    "/folders/{folderId}/subfolders": {
      "get": { "tags": ["Subfolders"], "summary": "List subfolders", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } },
      "post": { "tags": ["Subfolders"], "summary": "Create a subfolder", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "201": { "$ref": "#/components/responses/Success" } } },
      "patch": { "tags": ["Subfolders"], "summary": "Rename or move a subfolder", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } },
      "delete": { "tags": ["Subfolders"], "summary": "Delete a subfolder", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/keys": {
      "get": { "tags": ["API keys"], "summary": "List Folder key metadata", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } },
      "post": { "tags": ["API keys"], "summary": "Create a scoped API key", "description": "The full secret is returned once.", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "201": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/keys/{keyId}": {
      "delete": { "tags": ["API keys"], "summary": "Revoke an API key", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "name": "keyId", "in": "path", "required": true, "schema": { "type": "string" } }], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/webhooks": {
      "get": { "tags": ["Webhooks"], "summary": "List webhook metadata", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } },
      "post": { "tags": ["Webhooks"], "summary": "Create a signed webhook", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }], "responses": { "201": { "$ref": "#/components/responses/Success" } } }
    },
    "/folders/{folderId}/webhooks/{webhookId}": {
      "patch": { "tags": ["Webhooks"], "summary": "Update a webhook", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "$ref": "#/components/parameters/WebhookId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } },
      "delete": { "tags": ["Webhooks"], "summary": "Delete a webhook", "security": [{ "bearerAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/FolderId" }, { "$ref": "#/components/parameters/WebhookId" }], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/agent/capabilities": {
      "get": { "tags": ["Agent workflows"], "summary": "Discover Folder agent capabilities", "security": [], "responses": { "200": { "$ref": "#/components/responses/Success" } } }
    },
    "/agent/route": {
      "post": { "tags": ["Agent workflows"], "summary": "Route an agent workflow", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "request": { "type": "string" }, "workflow_id": { "type": "string" } } } } } }, "responses": { "200": { "$ref": "#/components/responses/Success" }, "400": { "$ref": "#/components/responses/BadRequest" } } }
    }
  },
  "components": {
    "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "Folder API key" } },
    "parameters": {
      "FolderId": { "name": "folderId", "in": "path", "required": true, "schema": { "type": "string" } },
      "FileId": { "name": "fileId", "in": "path", "required": true, "schema": { "type": "string" } },
      "WebhookId": { "name": "webhookId", "in": "path", "required": true, "schema": { "type": "string" } }
    },
    "schemas": {
      "CreateFolder": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "maxLength": 100 }, "description": { "type": "string" } } },
      "DirectUploadRequest": { "type": "object", "required": ["path", "content_type", "size"], "properties": { "path": { "type": "string", "maxLength": 500 }, "content_type": { "type": "string", "maxLength": 255 }, "size": { "type": "integer", "minimum": 1, "maximum": 5363466240 }, "tags": { "type": "array", "maxItems": 50, "items": { "type": "string", "maxLength": 100 } } } },
      "DirectUploadResponse": { "type": "object", "properties": { "upload": { "type": "object", "required": ["method", "url", "token", "expires_in", "required_headers", "max_bytes", "encryption"], "properties": { "method": { "const": "PUT" }, "url": { "type": "string", "format": "uri" }, "token": { "type": "string" }, "expires_in": { "type": "integer", "example": 900 }, "required_headers": { "type": "object", "additionalProperties": { "type": "string" } }, "max_bytes": { "type": "integer" }, "encryption": { "type": "object", "properties": { "mode": { "const": "r2-managed-aes-256" }, "application_layer_encrypted": { "const": false }, "note": { "type": "string" } } } } } } },
      "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string" } } }
    },
    "responses": {
      "Success": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } },
      "BadRequest": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Forbidden": { "description": "Insufficient permission or Folder scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "NotFound": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Conflict": { "description": "Path or state conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "Rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
