{"openapi":"3.1.0","info":{"title":"Clearvoyance agent API","version":"1.0.0","description":"Anonymous feedback from real people, by voice or text, with an AI report. Create an account (free; sandbox mode moves no money), top up by card, quote and launch campaigns. A campaign costs the flat price for its size, charged at launch. Every error carries a stable code and a message saying what to do next. The same operations are MCP tools at /mcp.","contact":{"email":"hello@clearvoyance.ai","url":"https://clearvoyance.ai/aeo"},"termsOfService":"https://clearvoyance.ai/terms"},"servers":[{"url":"https://clearvoyance.ai/api/v1"}],"externalDocs":{"description":"When to use Clearvoyance, and the recipe for post-purchase feedback","url":"https://clearvoyance.ai/aeo"},"paths":{"/pricing":{"get":{"operationId":"getPricing","summary":"The price list as data: flat price per campaign by size, the crypto reward fee, top-up limits","responses":{"200":{"description":"The price list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/accounts":{"post":{"operationId":"createAccount","summary":"Create an account and receive its API key once. Free; sandbox mode gives a notional $20 balance","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["live","sandbox"],"default":"live"},"label":{"type":"string","maxLength":200,"nullable":true}},"additionalProperties":false}}}},"responses":{"201":{"description":"The account and its key (shown once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account":{"get":{"operationId":"getAccount","summary":"The account behind the key: mode, balance, what is available","security":[{"apiKey":[]}],"responses":{"200":{"description":"The account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/ledger":{"get":{"operationId":"getLedger","summary":"Every movement of money on the account, newest first","security":[{"apiKey":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":100}}],"responses":{"200":{"description":"Ledger rows with the balance after each","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/close":{"post":{"operationId":"closeAccount","summary":"Preview (no body) or, with confirm: true, close the account and refund the unspent balance to the card that paid, less Stripe's fee","security":[{"apiKey":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"boolean","default":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"The preview or the result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/wallet":{"post":{"operationId":"setDepositWallet","summary":"Declare the Solana wallet USDC top-ups will come from","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"walletAddress":{"type":"string","minLength":32,"maxLength":44}},"required":["walletAddress"],"additionalProperties":false}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/topups":{"post":{"operationId":"createCardTopup","summary":"A Stripe Checkout link for a person to add money by card (live accounts only)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amountCents":{"type":"number"}},"required":["amountCents"],"additionalProperties":false}}}},"responses":{"201":{"description":"The checkout URL and session id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/topups/{sessionId}":{"get":{"operationId":"checkCardTopup","summary":"Whether a card top-up was paid, crediting it if so (idempotent)","security":[{"apiKey":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","pattern":"^cs_(test|live)_[A-Za-z0-9]{10,}$"}}],"responses":{"200":{"description":"The top-up status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/topups/{sessionId}/status":{"get":{"operationId":"topupStatus","summary":"Public status of a top-up session, for the page a person returns to after paying","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/quote":{"post":{"operationId":"quoteCampaign","summary":"Free: every problem with a campaign at once, its flat price, and whether the balance covers it","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["open_link"]},"title":{"type":"string","maxLength":200},"description":{"type":"string","maxLength":2000,"nullable":true},"senderName":{"type":"string","maxLength":120,"nullable":true},"questions":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":500}},"required":["text"],"additionalProperties":false},"maxItems":20},"giftText":{"type":"string","maxLength":1000,"nullable":true},"expiresInDays":{"type":"integer"},"responseCap":{"type":"integer"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["targeted"]},"title":{"type":"string","maxLength":200},"description":{"type":"string","maxLength":2000,"nullable":true},"senderName":{"type":"string","maxLength":120,"nullable":true},"questions":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":500}},"required":["text"],"additionalProperties":false},"maxItems":20},"giftText":{"type":"string","maxLength":1000,"nullable":true},"expiresInDays":{"type":"integer"},"cohortSize":{"type":"integer"},"minPercent":{"type":"integer"}},"required":["kind"],"additionalProperties":false}]}}}},"responses":{"200":{"description":"The quote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns":{"post":{"operationId":"launchCampaign","summary":"Create and launch a campaign; its flat price is charged from the balance at launch","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["open_link"]},"title":{"type":"string","maxLength":200},"description":{"type":"string","maxLength":2000,"nullable":true},"senderName":{"type":"string","maxLength":120,"nullable":true},"questions":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":500}},"required":["text"],"additionalProperties":false},"maxItems":20},"giftText":{"type":"string","maxLength":1000,"nullable":true},"expiresInDays":{"type":"integer"},"responseCap":{"type":"integer"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["targeted"]},"title":{"type":"string","maxLength":200},"description":{"type":"string","maxLength":2000,"nullable":true},"senderName":{"type":"string","maxLength":120,"nullable":true},"questions":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":500}},"required":["text"],"additionalProperties":false},"maxItems":20},"giftText":{"type":"string","maxLength":1000,"nullable":true},"expiresInDays":{"type":"integer"},"cohortEmails":{"type":"array","items":{"type":"string","format":"email"},"maxItems":500},"minPercent":{"type":"integer"}},"required":["kind","cohortEmails"],"additionalProperties":false}]}}}},"responses":{"201":{"description":"The live campaign and its share link or invitation links","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listCampaigns","summary":"The account's campaigns","security":[{"apiKey":[]}],"responses":{"200":{"description":"Campaigns","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}":{"get":{"operationId":"getCampaign","summary":"One campaign: status, answers, threshold, price charged","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"The campaign","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}/results":{"get":{"operationId":"getCampaignResults","summary":"The answers, once the privacy threshold is met","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Results, or why they are withheld","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}/analyze":{"post":{"operationId":"analyzeCampaign","summary":"An AI report over the answers","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"The report","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}/close":{"post":{"operationId":"closeCampaign","summary":"End the campaign now; the price was charged at launch","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Closed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"default":{"description":"A refusal or error: `code` is stable and `message` says what to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Authorization: Bearer cv_live_… or cv_test_…, from POST /accounts"}},"schemas":{"Ok":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"Error":{"type":"object","required":["ok","code","message"],"properties":{"ok":{"const":false},"code":{"type":"string","enum":["UNAUTHENTICATED","INVALID_KEY","KEY_REVOKED","RATE_LIMITED","VALIDATION","NOT_FOUND","INSUFFICIENT_BALANCE","SANDBOX_KEY","LIVE_KEY","INVALID_CAMPAIGN","CAMPAIGN_CLOSED","NOT_CONFIGURED","ALREADY_USED","WALLET_MISMATCH","NO_ANSWERS_YET","THRESHOLD_NOT_MET","DATA_DELETED","OPEN_CAMPAIGNS","ACCOUNT_CLOSING","BALANCE_CHANGED","SERVER_ERROR"]},"message":{"type":"string","description":"What went wrong and what to do next"},"field":{"type":"string"}},"additionalProperties":true}}}}