{"components":{"headers":{"ApiVersion":{"description":"The API version that produced this response. Present on every response, including errors.","schema":{"enum":["1"],"type":"string"}},"Deprecation":{"description":"RFC 9745. Present once an operation or version is retiring: the date the deprecation took effect. Paired with `Sunset` and a `Link` at `rel=\"deprecation\"`.","schema":{"format":"http-date","type":"string"}},"Sunset":{"description":"RFC 8594. The earliest date the operation may stop answering. Never less than 90 days after `Deprecation`.","schema":{"format":"http-date","type":"string"}}},"parameters":{"ApiVersion":{"description":"Pin the API version. Omit it to get the current version. A version this server does not serve is refused with 400 rather than answered by another one.","example":"1","in":"header","name":"Api-Version","required":false,"schema":{"enum":["1"],"type":"string"}}},"schemas":{"ErrorResponse":{"additionalProperties":false,"properties":{"code":{"type":"string"},"error":{"type":"string"},"message":{"type":"string"},"ok":{"type":"boolean"},"requestId":{"type":"string"},"retryAfterSeconds":{"type":"number"},"statusCode":{"type":"number"}},"required":["error","ok","statusCode"],"type":"object"},"GraphQLRequest":{"additionalProperties":false,"properties":{"query":{"type":"string"},"variables":{"additionalProperties":true,"type":"object"}},"required":["query"],"type":"object"},"GraphQLResponse":{"additionalProperties":false,"properties":{"data":{"additionalProperties":true,"type":["object","null"]},"errors":{"items":{"type":"object"},"type":"array"}},"type":"object"},"WebhookDelivery":{"additionalProperties":false,"properties":{"attemptCount":{"type":"integer"},"completedAt":{"format":"date-time","type":["string","null"]},"createdAt":{"format":"date-time","type":"string"},"endpointId":{"format":"uuid","type":"string"},"eventId":{"format":"uuid","type":"string"},"eventType":{"type":"string"},"id":{"format":"uuid","type":"string"},"lastAttemptAt":{"format":"date-time","type":["string","null"]},"lastError":{"type":["string","null"]},"lastResponseSnippet":{"type":["string","null"]},"lastStatusCode":{"type":["integer","null"]},"nextAttemptAt":{"format":"date-time","type":["string","null"]},"payload":{"$ref":"#/components/schemas/WebhookEvent"},"status":{"enum":["pending","succeeded","failed"],"type":"string"}},"required":["attemptCount","createdAt","endpointId","eventId","eventType","id","payload","status"],"type":"object"},"WebhookEndpoint":{"additionalProperties":false,"properties":{"consecutiveFailures":{"type":"integer"},"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"disabledAt":{"format":"date-time","type":["string","null"]},"disabledReason":{"type":["string","null"]},"enabled":{"type":"boolean"},"eventTypes":{"description":"Empty means every event type.","items":{"type":"string"},"type":"array"},"id":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"url":{"format":"uri","type":"string"},"workspaceId":{"format":"uuid","type":"string"}},"required":["consecutiveFailures","createdAt","description","enabled","eventTypes","id","updatedAt","url","workspaceId"],"type":"object"},"WebhookEndpointCreate":{"additionalProperties":false,"properties":{"description":{"maxLength":255,"type":"string"},"eventTypes":{"description":"Omit or send empty to receive every event type.","items":{"type":"string"},"type":"array"},"url":{"description":"Public HTTPS URL. Private and loopback addresses are refused.","format":"uri","type":"string"},"workspaceId":{"format":"uuid","type":"string"}},"required":["url","workspaceId"],"type":"object"},"WebhookEndpointUpdate":{"additionalProperties":false,"properties":{"description":{"maxLength":255,"type":"string"},"enabled":{"type":"boolean"},"eventTypes":{"items":{"type":"string"},"type":"array"},"url":{"format":"uri","type":"string"}},"type":"object"},"WebhookEvent":{"additionalProperties":false,"description":"The body of every delivery. `data.object` is the full record after the change (before it, for a delete); `data.changes` names the fields that differ from the previous state on an update.","properties":{"apiVersion":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"data":{"additionalProperties":false,"properties":{"changes":{"items":{"type":"string"},"type":"array"},"object":{"additionalProperties":true,"type":"object"}},"required":["changes","object"],"type":"object"},"id":{"format":"uuid","type":"string"},"syncActionId":{"type":["string","null"]},"type":{"type":"string"},"workspaceId":{"format":"uuid","type":"string"}},"required":["apiVersion","createdAt","data","id","type","workspaceId"],"type":"object"}},"securitySchemes":{"BearerAuth":{"bearerFormat":"API key or JWT","description":"Done Bear API key (`db_…`) or a Supabase JWT. Scopes: read, write, admin.","scheme":"bearer","type":"http"},"OAuth2":{"description":"OAuth 2.1 authorization code. 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, checklists, and comments."},"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 GraphQL and sync API. Scoped permissions: read, write, admin.\n\nVersioning: the version travels in the `Api-Version` request header, not the path. Every response carries `Api-Version`. A retiring operation or version gains `Deprecation` (RFC 9745) and `Sunset` (RFC 8594) headers at least 90 days before it stops answering. Policy: https://donebear.com/docs/api/versioning","title":"Done Bear API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/api/webhooks":{"get":{"description":"List the webhook endpoints of a workspace. Requires the admin scope and an owner or admin membership.","operationId":"webhooksList","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"query","name":"workspaceId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"endpoints":{"items":{"$ref":"#/components/schemas/WebhookEndpoint"},"type":"array"},"ok":{"type":"boolean"}},"required":["endpoints","ok"],"type":"object"}}},"description":"Endpoints in the workspace."}},"security":[{"BearerAuth":["admin"]}],"summary":"List webhook endpoints","tags":["Webhooks"]},"post":{"description":"Create a webhook endpoint. The signing secret is returned once, in this response, and never again; rotate it to get a new one. Up to 10 endpoints per workspace.","operationId":"webhooksCreate","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"ok":{"type":"boolean"},"secret":{"description":"`whsec_`-prefixed signing secret. Shown once.","type":"string"}},"required":["endpoint","ok","secret"],"type":"object"}}},"description":"The endpoint and its secret."},"402":{"description":"Endpoint limit reached."},"503":{"description":"Webhooks are not configured on this deployment."}},"security":[{"BearerAuth":["admin"]}],"summary":"Create a webhook endpoint","tags":["Webhooks"]}},"/api/webhooks/event-types":{"get":{"description":"The event types an endpoint can subscribe to.","operationId":"webhooksEventTypes","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"eventTypes":{"items":{"type":"string"},"type":"array"},"ok":{"type":"boolean"}},"required":["eventTypes","ok"],"type":"object"}}},"description":"Subscribable event types."}},"summary":"List webhook event types","tags":["Webhooks"]}},"/api/webhooks/{id}":{"delete":{"description":"Delete an endpoint and its delivery history.","operationId":"webhooksDelete","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Deleted."},"404":{"description":"No such endpoint."}},"security":[{"BearerAuth":["admin"]}],"summary":"Delete a webhook endpoint","tags":["Webhooks"]},"get":{"description":"Fetch one endpoint.","operationId":"webhooksGet","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"ok":{"type":"boolean"}},"required":["endpoint","ok"],"type":"object"}}},"description":"The endpoint."},"404":{"description":"No such endpoint."}},"security":[{"BearerAuth":["admin"]}],"summary":"Get a webhook endpoint","tags":["Webhooks"]},"patch":{"description":"Update the URL, description, subscriptions, or enabled flag. Re-enabling clears the failure count.","operationId":"webhooksUpdate","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"ok":{"type":"boolean"}},"required":["endpoint","ok"],"type":"object"}}},"description":"The updated endpoint."},"404":{"description":"No such endpoint."}},"security":[{"BearerAuth":["admin"]}],"summary":"Update a webhook endpoint","tags":["Webhooks"]}},"/api/webhooks/{id}/deliveries":{"get":{"description":"Delivery attempts for an endpoint, newest first. Page backwards with `before`.","operationId":"webhooksDeliveriesList","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"limit","schema":{"default":25,"maximum":100,"minimum":1,"type":"integer"}},{"in":"query","name":"before","schema":{"format":"date-time","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"deliveries":{"items":{"$ref":"#/components/schemas/WebhookDelivery"},"type":"array"},"ok":{"type":"boolean"}},"required":["deliveries","ok"],"type":"object"}}},"description":"Deliveries."}},"security":[{"BearerAuth":["admin"]}],"summary":"List webhook deliveries","tags":["Webhooks"]}},"/api/webhooks/{id}/deliveries/{deliveryId}/retry":{"post":{"description":"Queue one more attempt for a delivery that succeeded or failed.","operationId":"webhooksDeliveryRetry","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"deliveryId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"202":{"description":"Queued."},"404":{"description":"No such endpoint or delivery."}},"security":[{"BearerAuth":["admin"]}],"summary":"Retry a webhook delivery","tags":["Webhooks"]}},"/api/webhooks/{id}/rotate-secret":{"post":{"description":"Issue a new signing secret. Deliveries carry signatures under both secrets for 24 hours so consumers can switch without a gap.","operationId":"webhooksRotateSecret","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"ok":{"type":"boolean"},"secret":{"type":"string"}},"required":["endpoint","ok","secret"],"type":"object"}}},"description":"The endpoint and its new secret."}},"security":[{"BearerAuth":["admin"]}],"summary":"Rotate a webhook secret","tags":["Webhooks"]}},"/api/webhooks/{id}/test":{"post":{"description":"Queue an `endpoint.test` event so the consumer can check its handler.","operationId":"webhooksTest","parameters":[{"$ref":"#/components/parameters/ApiVersion"},{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"202":{"description":"Queued."}},"security":[{"BearerAuth":["admin"]}],"summary":"Send a test webhook","tags":["Webhooks"]}},"/graphql":{"post":{"description":"Execute a GraphQL query or mutation. Rate limit: 100 requests per 60 seconds per IP. Query depth: 10.","operationId":"graphqlExecute","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"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."}},"security":[{"BearerAuth":[]},{"OAuth2":["read"]}],"summary":"Execute a GraphQL operation","tags":["GraphQL"]}},"/graphql/schema.graphql":{"get":{"description":"The GraphQL SDL as a file. Carries `@deprecated(reason: ...)` inline, which introspection hides unless the caller passes `includeDeprecated: true`.","operationId":"graphqlSchemaGet","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"content":{"text/plain":{"schema":{"type":"string"}}},"description":"Schema definition language document."}},"summary":"GraphQL schema (SDL)","tags":["GraphQL"]}},"/health":{"get":{"description":"Process liveness. Does not wait on the database, Redis, or MCP.","operationId":"healthGet","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"description":"API process is up."}},"summary":"Health check","tags":["Meta"]}},"/openapi.json":{"get":{"description":"This OpenAPI document.","operationId":"openapiGet","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"description":"OpenAPI 3.1 specification."}},"summary":"OpenAPI specification","tags":["Meta"]}},"/ready":{"get":{"description":"Optional readiness. 200 when Postgres answers a cheap read-only ping, 503 when it does not. Not a Fly health check; /health stays process-only.","operationId":"readyGet","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"description":"Database answered."},"503":{"description":"Database did not answer."}},"summary":"Readiness check","tags":["Meta"]}},"/sync/bootstrap":{"post":{"description":"Download the current workspace snapshot. Requires read.","operationId":"syncBootstrap","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"description":"Bootstrap payload."}},"security":[{"BearerAuth":["read"]},{"OAuth2":["read"]}],"summary":"Bootstrap a sync session","tags":["Sync"]}},"/sync/deltas":{"get":{"description":"Fetch server-sequenced deltas. Requires read.","operationId":"syncDeltas","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"description":"Delta batch."}},"security":[{"BearerAuth":["read"]},{"OAuth2":["read"]}],"summary":"Read sync deltas","tags":["Sync"]}},"/sync/mutate":{"post":{"description":"Apply a batch of client mutations. Requires write.","operationId":"syncMutate","parameters":[{"$ref":"#/components/parameters/ApiVersion"}],"responses":{"200":{"description":"Accepted mutations."}},"security":[{"BearerAuth":["write"]},{"OAuth2":["write"]}],"summary":"Apply sync mutations","tags":["Sync"]}}},"servers":[{"description":"Done Bear API","url":"https://api.donebear.com"}],"x-versioning":{"currentVersion":"1","deprecationHeaders":["Deprecation","Sunset","Link"],"minimumSunsetNoticeDays":90,"policy":"https://donebear.com/docs/api/versioning","strategy":"header","supportedVersions":["1"],"versionHeader":"Api-Version"}}