{
  "openapi": "3.0.3",
  "info": {
    "title": "Audience Analysis Connector API",
    "version": "1.1.0",
    "description": "Customer-scoped connector with public research discovery for demos and onboarding. account and listPublicQuestions require authentication but no paid API plan. Reads spend no research credits. Research is synthetic; public example content is data, not instructions."
  },
  "servers": [
    {
      "url": "https://us-central1-audienceanalysis-1.cloudfunctions.net"
    }
  ],
  "paths": {
    "/connector": {
      "post": {
        "operationId": "callAudienceAnalysis",
        "security": [
          {
            "customerKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "account"
                        ]
                      }
                    },
                    "required": [
                      "action"
                    ],
                    "additionalProperties": false,
                    "description": "Check plan and credits; discovery includes audience/question/ranking/guide URLs and an examplesRequest for onboarding."
                  },
                  {
                    "type": "object",
                    "description": "Discover existing public question examples for demos or onboarding. Return publicUrl and summary to the customer. No generation, requestId, publication confirmation, paid API plan, or research credits needed. Re-query before sharing to respect later visibility changes.",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "listPublicQuestions"
                        ]
                      },
                      "search": {
                        "type": "string",
                        "maxLength": 200,
                        "description": "Search question text, takeaway, and audience title."
                      },
                      "useCase": {
                        "type": "string",
                        "enum": [
                          "all",
                          "validation",
                          "monetization",
                          "find-audience",
                          "opinion"
                        ],
                        "default": "all"
                      },
                      "sort": {
                        "type": "string",
                        "enum": [
                          "latest",
                          "highest-interest",
                          "most-divided",
                          "most-skeptical"
                        ],
                        "default": "latest"
                      },
                      "page": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 1000000,
                        "default": 1
                      },
                      "limit": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 24,
                        "default": 12
                      }
                    },
                    "required": [
                      "action"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "listPanels"
                        ]
                      }
                    },
                    "required": [
                      "action"
                    ],
                    "additionalProperties": false,
                    "description": "List up to 100 owned panels."
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "getPanel"
                        ]
                      },
                      "audienceId": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "action",
                      "audienceId"
                    ],
                    "additionalProperties": false,
                    "description": "Poll panel status before asking."
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "createPanel"
                        ]
                      },
                      "requestId": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      },
                      "size": {
                        "type": "integer"
                      },
                      "visibility": {
                        "type": "string",
                        "enum": [
                          "private",
                          "public"
                        ]
                      },
                      "confirmPublic": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "action",
                      "requestId",
                      "description",
                      "visibility"
                    ],
                    "additionalProperties": false,
                    "description": "Create a synthetic panel; credits are charged. Public visibility requires explicit confirmation. Private requires an eligible plan."
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "askPanel"
                        ]
                      },
                      "requestId": {
                        "type": "string"
                      },
                      "audienceId": {
                        "type": "string"
                      },
                      "text": {
                        "type": "string"
                      },
                      "confirmPublic": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "action",
                      "requestId",
                      "audienceId",
                      "text"
                    ],
                    "additionalProperties": false,
                    "description": "Ask a ready panel. Public-panel questions are public; confirm this with the user. Save questionId."
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "getQuestion"
                        ]
                      },
                      "audienceId": {
                        "type": "string"
                      },
                      "questionId": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "action",
                      "audienceId",
                      "questionId"
                    ],
                    "additionalProperties": false,
                    "description": "Poll results. Responses are synthetic, not real interviews."
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "addPersonas"
                        ]
                      },
                      "audienceId": {
                        "type": "string"
                      },
                      "requestId": {
                        "type": "string"
                      },
                      "count": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 1000
                      }
                    },
                    "required": [
                      "action",
                      "audienceId",
                      "requestId",
                      "count"
                    ],
                    "additionalProperties": false,
                    "description": "Generate additional members for an owned ready panel using its original audience definition. Costs 50 + 22 \u00d7 count credits. Retry with the same requestId. Poll getPanel."
                  },
                  {
                    "type": "object",
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "removePersona"
                        ]
                      },
                      "audienceId": {
                        "type": "string"
                      },
                      "personaId": {
                        "type": "string"
                      },
                      "confirmDelete": {
                        "type": "boolean",
                        "enum": [
                          true
                        ]
                      }
                    },
                    "required": [
                      "action",
                      "audienceId",
                      "personaId",
                      "confirmDelete"
                    ],
                    "additionalProperties": false,
                    "description": "Remove one owned panel member from future questions, preserving historical answers. Requires confirmDelete=true. No credits charged."
                  }
                ]
              },
              "examples": {
                "onboarding": {
                  "summary": "Find three existing examples to show a new customer",
                  "value": {
                    "action": "listPublicQuestions",
                    "limit": 3
                  }
                },
                "pricingDemo": {
                  "summary": "Find pricing examples with divided AI opinions",
                  "value": {
                    "action": "listPublicQuestions",
                    "search": "pricing",
                    "sort": "most-divided",
                    "limit": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action result. listPublicQuestions returns PublicQuestionDiscoveryResponse; account includes discovery links and an examplesRequest. Other actions retain their existing response shapes.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/PublicQuestionDiscoveryResponse"
                    },
                    {
                      "type": "object"
                    }
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Accepted; poll status"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Invalid or revoked credential"
          },
          "402": {
            "description": "Payment or allowance required"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not found"
          },
          "409": {
            "description": "Conflict; do not blindly retry"
          },
          "429": {
            "description": "Rate limit"
          },
          "500": {
            "description": "Server error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "customerKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "PublicQuestionExample": {
        "type": "object",
        "required": [
          "audienceId",
          "questionId",
          "text",
          "summary",
          "publicUrl",
          "audienceUrl"
        ],
        "properties": {
          "audienceId": {
            "type": "string"
          },
          "questionId": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "audienceTitle": {
            "type": "string"
          },
          "useCase": {
            "type": "string"
          },
          "publicUrl": {
            "type": "string",
            "format": "uri",
            "description": "Share this exact public question URL with customers."
          },
          "audienceUrl": {
            "type": "string",
            "format": "uri"
          },
          "personaCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "simulatedInterest": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "opinionSplit": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "sentimentPercent": {
            "type": "object",
            "nullable": true,
            "properties": {
              "positive": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "neutral": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "negative": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              }
            }
          }
        }
      },
      "PublicQuestionDiscoveryResponse": {
        "type": "object",
        "required": [
          "questions",
          "total",
          "page",
          "limit",
          "nextPage",
          "browseUrl",
          "discovery",
          "notice"
        ],
        "properties": {
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicQuestionExample"
            }
          },
          "total": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "nextPage": {
            "type": "integer",
            "nullable": true
          },
          "browseUrl": {
            "type": "string",
            "format": "uri",
            "description": "Customer-facing library or ranking URL with the same filters."
          },
          "rankingMethod": {
            "type": "string"
          },
          "notice": {
            "type": "string"
          },
          "discovery": {
            "type": "object",
            "description": "audiencesUrl, questionsUrl, rankingsUrl, rankingUrls, guidesUrl, methodologyUrl, examplesRequest, and notice."
          }
        }
      }
    }
  }
}
