{
  "components": {
    "schemas": {
      "ErrorResponse": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          },
          "statusCode": {
            "type": "integer"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "GraphQLRequest": {
        "additionalProperties": false,
        "properties": {
          "operationName": {
            "type": [
              "string",
              "null"
            ]
          },
          "query": {
            "type": "string"
          },
          "variables": {
            "additionalProperties": true,
            "type": "object"
          }
        },
        "required": [
          "query"
        ],
        "type": "object"
      },
      "GraphQLResponse": {
        "additionalProperties": false,
        "properties": {
          "data": {
            "additionalProperties": true,
            "type": [
              "object",
              "null"
            ]
          },
          "errors": {
            "items": {
              "$ref": "#/components/schemas/GraphQLTopLevelError"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "GraphQLTopLevelError": {
        "additionalProperties": false,
        "properties": {
          "extensions": {
            "additionalProperties": false,
            "properties": {
              "code": {
                "description": "Typed domain code such as WORKSPACE_NOT_FOUND or ACCESS_DENIED.",
                "type": "string"
              }
            },
            "type": "object"
          },
          "message": {
            "type": "string"
          },
          "path": {
            "items": {
              "type": [
                "string",
                "integer"
              ]
            },
            "type": "array"
          }
        },
        "required": [
          "message"
        ],
        "type": "object"
      },
      "HealthResponse": {
        "additionalProperties": true,
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "type": "object"
      },
      "SyncMutateRequest": {
        "additionalProperties": true,
        "description": "Server-sequenced mutation batch. Field names follow the sync protocol, not GraphQL.",
        "properties": {
          "actions": {
            "items": {
              "type": "object"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "UserError": {
        "additionalProperties": false,
        "description": "Typed GraphQL mutation error. Also returned on mutation payloads as `errors`.",
        "properties": {
          "code": {
            "type": "string"
          },
          "field": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "BearerAuth": {
        "bearerFormat": "API key or JWT",
        "description": "Done Bear API key (`db_…`) or a Supabase JWT. API keys carry scoped permissions: `read`, `write`, and `admin`.",
        "scheme": "bearer",
        "type": "http"
      },
      "OAuth2": {
        "description": "OAuth 2.1 authorization code for the hosted MCP server and API. Request only the scopes the agent needs.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://mcp.donebear.com/authorize",
            "scopes": {
              "admin": "Manage workspaces, billing, members, and API keys.",
              "read": "Read tasks, projects, labels, teams, and workspace metadata.",
              "write": "Create and update tasks, projects, labels, and checklists."
            },
            "tokenUrl": "https://mcp.donebear.com/token"
          }
        },
        "type": "oauth2"
      }
    }
  },
  "externalDocs": {
    "description": "Done Bear developer resources",
    "url": "https://donebear.com/developers"
  },
  "info": {
    "contact": {
      "email": "hello@donebear.com",
      "name": "Done Bear",
      "url": "https://donebear.com/contact"
    },
    "description": "Done Bear is a local-first GTD task manager.\nUse GraphQL for reads and workspace administration, `/sync/mutate` for task writes,\nand the hosted MCP server for agent tools.\n\nScoped permissions:\n- `read`: list and show tasks, projects, labels, and teams\n- `write`: create and edit those records (includes `read`)\n- `admin`: workspaces, billing, members, and API keys (includes `write` and `read`)\n\nMCP OAuth advertises `read` and `write`. API keys accept `read`, `write`, and `admin`.",
    "license": {
      "name": "Proprietary",
      "url": "https://donebear.com/terms"
    },
    "title": "Done Bear API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/graphql": {
      "post": {
        "description": "Execute a GraphQL query or mutation. Task writes belong on `/sync/mutate`. Query depth is capped at 10. Rate limit: 100 requests per 60 seconds per IP.",
        "operationId": "graphqlExecute",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GraphQLRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphQLResponse"
                }
              }
            },
            "description": "GraphQL execution result. Domain failures also appear as typed `UserError` objects on mutation payloads."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Missing or invalid bearer credentials."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate limit exceeded."
          }
        },
        "security": [
          {
            "BearerAuth": []
          },
          {
            "OAuth2": [
              "read"
            ]
          }
        ],
        "summary": "Execute a GraphQL operation",
        "tags": [
          "GraphQL"
        ]
      }
    },
    "/health": {
      "get": {
        "description": "Liveness and database ping for the API origin.",
        "operationId": "healthGet",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            },
            "description": "API process is up."
          }
        },
        "summary": "Health check",
        "tags": [
          "Meta"
        ]
      }
    },
    "/openapi.json": {
      "get": {
        "description": "This OpenAPI document.",
        "operationId": "openapiGet",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "OpenAPI 3.1 specification."
          }
        },
        "summary": "OpenAPI specification",
        "tags": [
          "Meta"
        ]
      }
    },
    "/sync/bootstrap": {
      "post": {
        "description": "Download the current workspace snapshot for a sync client. Requires `read`.",
        "operationId": "syncBootstrap",
        "responses": {
          "200": {
            "description": "Bootstrap payload for the requesting workspace."
          },
          "401": {
            "description": "Missing or invalid bearer credentials."
          }
        },
        "security": [
          {
            "BearerAuth": [
              "read"
            ]
          },
          {
            "OAuth2": [
              "read"
            ]
          }
        ],
        "summary": "Bootstrap a sync session",
        "tags": [
          "Sync"
        ]
      }
    },
    "/sync/deltas": {
      "get": {
        "description": "Fetch server-sequenced deltas since a client cursor. Requires `read`.",
        "operationId": "syncDeltas",
        "parameters": [
          {
            "description": "Last applied sync id.",
            "in": "query",
            "name": "after",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delta batch."
          },
          "401": {
            "description": "Missing or invalid bearer credentials."
          }
        },
        "security": [
          {
            "BearerAuth": [
              "read"
            ]
          },
          {
            "OAuth2": [
              "read"
            ]
          }
        ],
        "summary": "Read sync deltas",
        "tags": [
          "Sync"
        ]
      }
    },
    "/sync/mutate": {
      "post": {
        "description": "Apply a batch of client mutations (task create/update/delete and related models). Requires `write`.",
        "operationId": "syncMutate",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncMutateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Accepted mutations and the new last sync id."
          },
          "401": {
            "description": "Missing or invalid bearer credentials."
          }
        },
        "security": [
          {
            "BearerAuth": [
              "write"
            ]
          },
          {
            "OAuth2": [
              "write"
            ]
          }
        ],
        "summary": "Apply sync mutations",
        "tags": [
          "Sync"
        ]
      }
    }
  },
  "servers": [
    {
      "description": "Done Bear API",
      "url": "https://api.donebear.com"
    },
    {
      "description": "Hosted MCP server (Streamable HTTP)",
      "url": "https://mcp.donebear.com"
    },
    {
      "description": "Public marketing origin for discovery files",
      "url": "https://donebear.com"
    }
  ],
  "tags": [
    {
      "description": "GraphQL reads and workspace administration.",
      "externalDocs": {
        "url": "https://donebear.com/docs/api/graphql"
      },
      "name": "GraphQL"
    },
    {
      "description": "Server-sequenced local-first sync protocol.",
      "name": "Sync"
    },
    {
      "description": "Health and machine-readable catalogs.",
      "name": "Meta"
    }
  ]
}