{
  "openapi": "3.0.3",
  "info": {
    "title": "Doop Public API",
    "version": "1.0.0",
    "description": "OAuth API for all active Doop accounts; no paid subscription is required. Feed and Watch resource IDs use feed_ and watch_ prefixes."
  },
  "servers": [
    {
      "url": "https://doop.live"
    }
  ],
  "paths": {
    "/api/v1/me": {
      "get": {
        "summary": "Connected account",
        "operationId": "get_me",
        "security": [
          {
            "DoopOAuth": [
              "profile:read"
            ]
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "username": {
                          "type": "string"
                        },
                        "display_name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "username",
                        "display_name"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "9cae713a-e731-40be-8c77-53bdfab2fd60",
                    "username": "amara",
                    "display_name": "Amara Mensah"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "invalid_token",
                    "message": "Access token is invalid or expired.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Identify the account that authorized this connection. Only the public ID, username, and display name are returned. ",
        "tags": [
          "Account"
        ]
      }
    },
    "/api/v1/posts": {
      "get": {
        "summary": "List owned posts",
        "operationId": "get_posts",
        "security": [
          {
            "DoopOAuth": [
              "posts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the preceding page. Newest first."
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "feed",
                "watch"
              ],
              "default": "feed"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "body": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "body",
                          "created_at",
                          "type"
                        ]
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983",
                      "body": "What would make your workflow easier?",
                      "created_at": "2026-10-11T10:00:00.000Z",
                      "type": "feed"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_TYPE",
                    "message": "Choose feed or watch.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "List the connected account\u2019s visible Feed posts or approved native Watch videos, newest first. Feed and Watch have separate cursors. This does not list another user\u2019s posts or publish new content.",
        "tags": [
          "Posts & comments"
        ]
      }
    },
    "/api/v1/posts/{id}": {
      "get": {
        "summary": "Read an owned post",
        "operationId": "get_posts_id",
        "security": [
          {
            "DoopOAuth": [
              "posts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "body": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "body",
                        "created_at",
                        "type"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983",
                    "body": "What would make your workflow easier?",
                    "created_at": "2026-10-11T10:00:00.000Z",
                    "type": "feed"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Resource is not available.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Retrieve a visible post owned by the connected account. Watch responses use type: watch and a watch_ ID; body contains the video caption. Media URLs and uploads are outside v1.",
        "tags": [
          "Posts & comments"
        ]
      }
    },
    "/api/v1/posts/{id}/comments": {
      "get": {
        "summary": "List top-level comments",
        "operationId": "get_posts_id_comments",
        "security": [
          {
            "DoopOAuth": [
              "comments:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the preceding page. Newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "body": {
                            "type": "string"
                          },
                          "author_user_id": {
                            "type": "string"
                          },
                          "author_username": {
                            "type": "string",
                            "nullable": true
                          },
                          "parent_id": {
                            "type": "string",
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "post_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "body",
                          "author_user_id",
                          "parent_id",
                          "created_at",
                          "post_id"
                        ]
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "feed_7973721b-a18c-4da5-90f5-bad85016ce00",
                      "body": "Can this connect to our support tools?",
                      "author_user_id": "82ba212a-b26b-4c2e-8edc-d8376638a0c2",
                      "author_username": "kwame",
                      "parent_id": null,
                      "created_at": "2026-10-11T10:00:00.000Z",
                      "post_id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Resource is not available.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Read top-level comments on one of your Feed or Watch posts. Replies are retrieved separately. Deleted or moderated comments and comments from blocked contacts are excluded. Other users\u2019 posts return 404.",
        "tags": [
          "Posts & comments"
        ]
      }
    },
    "/api/v1/comments/{id}/replies": {
      "get": {
        "summary": "List replies",
        "operationId": "get_comments_id_replies",
        "security": [
          {
            "DoopOAuth": [
              "comments:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the preceding page. Newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "body": {
                            "type": "string"
                          },
                          "author_user_id": {
                            "type": "string"
                          },
                          "author_username": {
                            "type": "string",
                            "nullable": true
                          },
                          "parent_id": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "post_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "body",
                          "author_user_id",
                          "parent_id",
                          "created_at",
                          "post_id"
                        ]
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "feed_c3164828-a34c-47a8-9a3b-1d8db3969ec1",
                      "body": "Yes, you can connect them through the API.",
                      "author_user_id": "9cae713a-e731-40be-8c77-53bdfab2fd60",
                      "author_username": "amara",
                      "parent_id": "feed_7973721b-a18c-4da5-90f5-bad85016ce00",
                      "created_at": "2026-10-11T10:00:00.000Z",
                      "post_id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Resource is not available.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Read replies attached to a root comment on your own post. ",
        "tags": [
          "Posts & comments"
        ]
      },
      "post": {
        "summary": "Reply to a comment",
        "operationId": "post_comments_id_replies",
        "security": [
          {
            "DoopOAuth": [
              "comments:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "body": {
                          "type": "string"
                        },
                        "author_user_id": {
                          "type": "string"
                        },
                        "author_username": {
                          "type": "string",
                          "nullable": true
                        },
                        "parent_id": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "post_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "body",
                        "author_user_id",
                        "parent_id",
                        "created_at",
                        "post_id"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "feed_c3164828-a34c-47a8-9a3b-1d8db3969ec1",
                    "body": "Yes, you can connect them through the API.",
                    "author_user_id": "9cae713a-e731-40be-8c77-53bdfab2fd60",
                    "author_username": "amara",
                    "parent_id": "feed_7973721b-a18c-4da5-90f5-bad85016ce00",
                    "created_at": "2026-10-11T10:00:00.000Z",
                    "post_id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "REQUEST_REJECTED",
                    "message": "Comments are disabled for this video.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 800
                  }
                },
                "required": [
                  "body"
                ]
              },
              "example": {
                "body": "Yes, you can connect them through the API."
              }
            }
          }
        },
        "description": "Reply as the connected account on its own Feed or Watch post. Replying to a reply attaches your reply to the root thread. Existing commenting and safety restrictions apply.",
        "tags": [
          "Posts & comments"
        ]
      }
    },
    "/api/v1/users/by-username/{username}": {
      "get": {
        "summary": "Resolve a public username",
        "operationId": "get_users_by-username_username",
        "security": [
          {
            "DoopOAuth": [
              "profile:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "username": {
                          "type": "string"
                        },
                        "display_name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "username",
                        "display_name"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "82ba212a-b26b-4c2e-8edc-d8376638a0c2",
                    "username": "kojo",
                    "display_name": "Kojo Owusu"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Resource is not available.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Resolve a public username before starting a conversation. No email or phone search is available. Inactive and blocked users are not returned. The recipient does not need a paid plan.",
        "tags": [
          "Conversations & messages"
        ]
      }
    },
    "/api/v1/conversations": {
      "get": {
        "summary": "List conversations",
        "operationId": "get_conversations",
        "security": [
          {
            "DoopOAuth": [
              "conversations:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the preceding page. Newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "context_type": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "closed_at": {
                            "type": "string",
                            "nullable": true
                          },
                          "message_request_state": {
                            "type": "string"
                          },
                          "other_user_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "context_type",
                          "created_at",
                          "closed_at",
                          "message_request_state",
                          "other_user_id"
                        ]
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f85a71e9-6d88-4fbe-b1bb-d9371044f568",
                      "context_type": "DIRECT",
                      "created_at": "2026-10-11T10:00:00.000Z",
                      "closed_at": null,
                      "message_request_state": "PENDING",
                      "other_user_id": "82ba212a-b26b-4c2e-8edc-d8376638a0c2"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "This connection does not have the required permission.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "List conversations accessible to the connected account, ordered by creation time, newest first. Includes accessible direct and work conversations. A non-null closed_at means read-only. Listing a message request does not mean it has been accepted.",
        "tags": [
          "Conversations & messages"
        ]
      },
      "post": {
        "summary": "Find or create a direct conversation",
        "operationId": "post_conversations",
        "security": [
          {
            "DoopOAuth": [
              "conversations:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "f85a71e9-6d88-4fbe-b1bb-d9371044f568"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "REQUEST_REJECTED",
                    "message": "Contact is unavailable between these accounts.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "recipient_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "recipient_id"
                ]
              },
              "example": {
                "recipient_id": "82ba212a-b26b-4c2e-8edc-d8376638a0c2"
              }
            }
          }
        },
        "description": "Find an existing eligible direct conversation or create one with a permitted active recipient. Concurrent requests reuse the existing direct-conversation rules. Returns 201 with the conversation ID whether found or created. Starting a conversation sends no text message and does not bypass message-request rules.",
        "tags": [
          "Conversations & messages"
        ]
      }
    },
    "/api/v1/conversations/{id}/messages": {
      "get": {
        "summary": "List visible text messages",
        "operationId": "get_conversations_id_messages",
        "security": [
          {
            "DoopOAuth": [
              "messages:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque next_cursor from the preceding page. Newest first."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "conversation_id": {
                            "type": "string"
                          },
                          "sender_user_id": {
                            "type": "string"
                          },
                          "body": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "conversation_id",
                          "sender_user_id",
                          "body",
                          "created_at"
                        ]
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "next_cursor"
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "b67c0875-60a4-4c29-8bcb-759a5a29ea75",
                      "conversation_id": "f85a71e9-6d88-4fbe-b1bb-d9371044f568",
                      "sender_user_id": "9cae713a-e731-40be-8c77-53bdfab2fd60",
                      "body": "Hello! Thanks for reaching out.",
                      "created_at": "2026-10-11T10:00:00.000Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Resource is not available.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Read visible user messages in a conversation you can access. Internal system messages, card metadata, and attachments are excluded. ",
        "tags": [
          "Conversations & messages"
        ]
      },
      "post": {
        "summary": "Send a text message",
        "operationId": "post_conversations_id_messages",
        "security": [
          {
            "DoopOAuth": [
              "messages:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "conversation_id": {
                          "type": "string"
                        },
                        "sender_user_id": {
                          "type": "string"
                        },
                        "body": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "conversation_id",
                        "sender_user_id",
                        "body",
                        "created_at"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "b67c0875-60a4-4c29-8bcb-759a5a29ea75",
                    "conversation_id": "f85a71e9-6d88-4fbe-b1bb-d9371044f568",
                    "sender_user_id": "9cae713a-e731-40be-8c77-53bdfab2fd60",
                    "body": "Hello! Thanks for reaching out.",
                    "created_at": "2026-10-11T10:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "REQUEST_REJECTED",
                    "message": "This conversation is read-only.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "body"
                ]
              },
              "example": {
                "body": "Hello! Thanks for reaching out."
              }
            }
          }
        },
        "description": "Send a text message as the connected account. Works in existing and newly created permitted conversations. Message-request restrictions, recipient blocking, and domain sending limits still apply. A second introduction may be rejected until the recipient accepts. Bulk sending and attachments are unsupported.",
        "tags": [
          "Conversations & messages"
        ]
      }
    },
    "/api/v1/webhooks/events/{id}": {
      "get": {
        "summary": "Retrieve an attempted webhook event",
        "operationId": "get_webhook_event",
        "security": [
          {
            "DoopOAuth": [
              "webhooks:manage"
            ]
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authoritative event with current resource data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "api_version",
                        "created_at",
                        "data"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "comment.created",
                            "comment.replied",
                            "message.received",
                            "post.published"
                          ]
                        },
                        "api_version": {
                          "type": "string",
                          "enum": [
                            "v1"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "originating_app_id": {
                          "type": "string",
                          "nullable": true
                        },
                        "data": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "body": {
                                  "type": "string"
                                },
                                "author_user_id": {
                                  "type": "string"
                                },
                                "author_username": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "parent_id": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "created_at": {
                                  "type": "string"
                                },
                                "post_id": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id",
                                "body",
                                "author_user_id",
                                "parent_id",
                                "created_at",
                                "post_id"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "conversation_id": {
                                  "type": "string"
                                },
                                "sender_user_id": {
                                  "type": "string"
                                },
                                "body": {
                                  "type": "string"
                                },
                                "created_at": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id",
                                "conversation_id",
                                "sender_user_id",
                                "body",
                                "created_at"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "body": {
                                  "type": "string"
                                },
                                "created_at": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id",
                                "body",
                                "created_at",
                                "type"
                              ]
                            }
                          ],
                          "description": "A comment/reply, message, or post, determined by event type."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "122da9c3-2ed9-4702-82dc-5d72b6ac76fb",
                    "type": "comment.created",
                    "api_version": "v1",
                    "created_at": "2026-10-11T10:00:00.000Z",
                    "originating_app_id": null,
                    "data": {
                      "id": "feed_7973721b-a18c-4da5-90f5-bad85016ce00",
                      "body": "Can this connect to our support tools?",
                      "author_user_id": "82ba212a-b26b-4c2e-8edc-d8376638a0c2",
                      "author_username": "kwame",
                      "parent_id": null,
                      "created_at": "2026-10-11T10:00:00.000Z",
                      "post_id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "This connection does not have the required permission.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Event not delivered to this active connection, filtered, expired, or resource inaccessible",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Webhook event unavailable.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Retrieve authoritative event data using OAuth. For queued consumers such as Zapier, treat a callback only as an untrusted event ID and use this response instead of its payload. Requires an attempted delivery to an active subscription belonging to this exact OAuth connection. Current event scopes, subscription filters, and resource access are rechecked. Events are retained for 30 days; resources reflect their current state. Deduplicate by event ID. This authenticated retrieval is an alternative to trusting the callback body; ordinary receivers should still verify signatures at receipt.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "summary": "List webhook subscriptions",
        "operationId": "get_webhooks",
        "security": [
          {
            "DoopOAuth": [
              "webhooks:manage"
            ]
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "events": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "post_filter": {
                            "type": "string",
                            "nullable": true
                          },
                          "ignore_own_app": {
                            "type": "boolean"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "disabled_at": {
                            "type": "string",
                            "nullable": true
                          }
                        },
                        "required": [
                          "id",
                          "url",
                          "events",
                          "post_filter",
                          "ignore_own_app",
                          "created_at",
                          "disabled_at"
                        ]
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "917d36dd-6d59-40b2-93a8-c1fc6d69a31a",
                      "url": "https://example.com/webhooks/doop",
                      "events": [
                        "comment.created",
                        "comment.replied"
                      ],
                      "post_filter": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983",
                      "ignore_own_app": true,
                      "created_at": "2026-10-11T10:00:00.000Z",
                      "disabled_at": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "This connection does not have the required permission.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "List subscriptions belonging to this OAuth connection. Returns at most 100 subscriptions, newest first, including disabled subscriptions. No cursor and no signing secrets are returned.",
        "tags": [
          "Webhooks"
        ]
      },
      "post": {
        "summary": "Subscribe to events",
        "operationId": "post_webhooks",
        "security": [
          {
            "DoopOAuth": [
              "webhooks:manage"
            ]
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "post_filter": {
                          "type": "string",
                          "nullable": true
                        },
                        "ignore_own_app": {
                          "type": "boolean"
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "signing_secret": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "url",
                        "events",
                        "post_filter",
                        "ignore_own_app",
                        "created_at",
                        "signing_secret"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "data": {
                    "id": "917d36dd-6d59-40b2-93a8-c1fc6d69a31a",
                    "url": "https://example.com/webhooks/doop",
                    "events": [
                      "comment.created",
                      "comment.replied"
                    ],
                    "post_filter": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983",
                    "ignore_own_app": true,
                    "created_at": "2026-10-11T10:00:00.000Z",
                    "signing_secret": "example_only_save_the_real_secret_securely"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_WEBHOOK_URL",
                    "message": "Webhook must resolve only to public addresses.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "enum": [
                        "comment.created",
                        "comment.replied",
                        "message.received",
                        "post.published"
                      ]
                    }
                  },
                  "post_id": {
                    "type": "string",
                    "nullable": true,
                    "description": "Owned post ID. Omit or pass null for all eligible posts. Do not filter message.received by post."
                  },
                  "ignore_own_app": {
                    "type": "boolean",
                    "default": true
                  }
                },
                "required": [
                  "url",
                  "events"
                ]
              },
              "example": {
                "url": "https://example.com/webhooks/doop",
                "events": [
                  "comment.created",
                  "comment.replied"
                ],
                "post_id": "feed_0ebecbdb-d0a7-473a-b610-58c03a40f983",
                "ignore_own_app": true
              }
            }
          }
        },
        "description": "Subscribe to new activity on the connected account. Save the signing_secret from this response; it is not included in subscription lists. Maximum ten active subscriptions per connection. Historical records are available through list endpoints.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/api/v1/webhooks/{id}": {
      "delete": {
        "summary": "Remove webhook subscription",
        "operationId": "delete_webhooks_id",
        "security": [
          {
            "DoopOAuth": [
              "webhooks:manage"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "deleted"
                  ]
                },
                "example": {
                  "deleted": true
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "invalid_token",
                    "message": "Access token is invalid or expired.",
                    "request_id": "cb5a1325-ff88-4453-8cd2-aa8fc4127eaf"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Missing permission or inactive account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unavailable resource",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or domain restriction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Feature disabled or unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Disable a subscription owned by this connection. Repeating the request is safe. Requires a valid access token. Available regardless of subscription. Use Settings \u2192 Integrations to disconnect if your access token has expired. A subscription not owned by this connection is left untouched.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/oauth/token": {
      "post": {
        "summary": "Exchange credentials",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "refresh_token"
                    ]
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string"
                  },
                  "code_verifier": {
                    "type": "string"
                  },
                  "refresh_token": {
                    "type": "string"
                  }
                },
                "required": [
                  "client_id",
                  "client_secret",
                  "grant_type"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OAuth response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "enum": [
                        "Bearer"
                      ]
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 900
                    },
                    "scope": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "access_token",
                    "refresh_token",
                    "token_type",
                    "expires_in",
                    "scope"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "OAuth error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "401": {
            "description": "Client authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "summary": "Revoke a connection",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "token": {
                    "type": "string"
                  }
                },
                "required": [
                  "client_id",
                  "client_secret",
                  "token"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OAuth response"
          },
          "400": {
            "description": "OAuth error"
          },
          "401": {
            "description": "Client authentication failed"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "DoopOAuth": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://doop.live/oauth/authorize",
            "tokenUrl": "https://doop.live/oauth/token",
            "scopes": {
              "profile:read": "profile read",
              "posts:read": "posts read",
              "comments:read": "comments read",
              "comments:write": "comments write",
              "conversations:read": "conversations read",
              "conversations:write": "conversations write",
              "messages:read": "messages read",
              "messages:write": "messages write",
              "webhooks:manage": "webhooks manage"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              }
            }
          }
        }
      },
      "OAuthError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "error_description": {
            "type": "string"
          }
        },
        "required": [
          "error",
          "error_description"
        ]
      }
    }
  }
}
