{"openapi":"3.1.0","info":{"title":"Two Fires Engine","version":"1.0.0","summary":"Four marketing research agents, metered per run.","description":"Customer Insight, Messaging Audit, Competitor and Category, and an AI visibility check, exposed as a plain JSON API and as an MCP server at /mcp.\n\nEvery POST is asynchronous: it returns 202 with a run_id. Poll GET /v1/runs/{id}, or pass callback_url and be told when it finishes.\n\nCredits are dollars, not runs. Every response carries X-TwoFires-Credits-Remaining.","contact":{"name":"Two Fires","url":"https://www.two-fires.com"},"license":{"name":"Proprietary","url":"https://www.two-fires.com/#terms"}},"servers":[{"url":"https://engine.two-fires.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your API key, as \"Authorization: Bearer tfe_live_...\"."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"topup_url":{"type":"string","description":"Where to buy more credits. Present on 402 only."}}}}},"Run":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid"},"tool":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed"]},"credits_charged":{"type":"number"},"started_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"result":{"type":["object","null"],"description":"Present once status is done."},"pdf_url":{"type":["string","null"]},"error":{"type":"string"}}}}},"paths":{"/v1/insight":{"post":{"summary":"Run a Customer Insight","description":"Researches what buyers in a market actually say: their pain points, the questions they ask before buying, and the words they use. Evidence-labelled and confidence-labelled.\n\nCosts AUD 49 in credits.","operationId":"post_v1_insight","responses":{"202":{"description":"Accepted. Poll GET /v1/runs/{id}.","headers":{"X-TwoFires-Credits-Remaining":{"schema":{"type":"number"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid"},"status":{"type":"string"},"poll":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Not enough credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"This run costs AUD 49.","topup_url":"https://engine.two-fires.com/pricing"}}}}},"429":{"description":"Rate limited. Retry-After is set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["product","market","region","customer"],"properties":{"product":{"type":"string","description":"What you sell."},"market":{"type":"string","description":"The market or category you sell into."},"region":{"type":"string","description":"Where your customers are."},"customer":{"type":"string","description":"Who the customer is, in a sentence or two."},"website":{"type":"string","description":"Your website, if you have one."},"competitors":{"type":"string"},"testimonials":{"type":"string"},"offer":{"type":"string"},"callback_url":{"type":"string","description":"POSTed when the run finishes."}}},"example":{"product":"Physiotherapy and clinical exercise for post-surgical recovery","market":"Allied health, private physiotherapy clinics","region":"Dee Why, Northern Beaches, Sydney","customer":"Adults 40 to 70 recovering from knee or shoulder surgery, referred by a surgeon or GP","website":"https://www.two-fires.com/samples/demo/"}}}}}},"/v1/audit":{"post":{"summary":"Run a Messaging Audit","description":"Audits a homepage against what customers actually care about: value proposition clarity, whether it speaks the customer's language, proof, differentiation, and the next step it offers.\n\nCosts AUD 29 in credits.","operationId":"post_v1_audit","responses":{"202":{"description":"Accepted. Poll GET /v1/runs/{id}.","headers":{"X-TwoFires-Credits-Remaining":{"schema":{"type":"number"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid"},"status":{"type":"string"},"poll":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Not enough credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"This run costs AUD 29.","topup_url":"https://engine.two-fires.com/pricing"}}}}},"429":{"description":"Rate limited. Retry-After is set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["site_url"],"properties":{"site_url":{"type":"string","description":"The page to audit."},"extra_assets":{"type":"string","description":"Any other copy to consider: ads, a deck, an email."},"insight_run_id":{"type":"string","description":"A finished /v1/insight run to audit against. Without one, a Customer Insight is run first and both are charged."},"callback_url":{"type":"string"}}},"example":{"site_url":"https://www.two-fires.com/samples/demo/"}}}}}},"/v1/category":{"post":{"summary":"Run a Competitor and Category scan","description":"Maps what everyone in a category is claiming, where the claims collapse into sameness, and which position is actually open.\n\nCosts AUD 79 in credits.","operationId":"post_v1_category","responses":{"202":{"description":"Accepted. Poll GET /v1/runs/{id}.","headers":{"X-TwoFires-Credits-Remaining":{"schema":{"type":"number"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid"},"status":{"type":"string"},"poll":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Not enough credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"This run costs AUD 79.","topup_url":"https://engine.two-fires.com/pricing"}}}}},"429":{"description":"Rate limited. Retry-After is set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["product","market","region","website"],"properties":{"product":{"type":"string"},"market":{"type":"string"},"region":{"type":"string"},"website":{"type":"string"},"competitors":{"type":"string"},"substitutes":{"type":"string"},"callback_url":{"type":"string"}}},"example":{"product":"Physiotherapy and clinical exercise for post-surgical recovery","market":"Private physiotherapy clinics","region":"Northern Beaches, Sydney","website":"https://www.two-fires.com/samples/demo/"}}}}}},"/v1/visibility":{"post":{"summary":"Run an AI visibility check","description":"Asks AI assistants the questions a customer would ask when looking for a provider in a category and region, then reports who gets named, how often no one is named at all, and how concentrated the naming is. 92 questions by default.\n\nCosts AUD 39 in credits.","operationId":"post_v1_visibility","responses":{"202":{"description":"Accepted. Poll GET /v1/runs/{id}.","headers":{"X-TwoFires-Credits-Remaining":{"schema":{"type":"number"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid"},"status":{"type":"string"},"poll":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Not enough credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"This run costs AUD 39.","topup_url":"https://engine.two-fires.com/pricing"}}}}},"429":{"description":"Rate limited. Retry-After is set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["category","region"],"properties":{"category":{"type":"string","description":"The category a customer would search in."},"region":{"type":"string"},"brand":{"type":"string","description":"A business name to count mentions of."},"questions":{"type":"array","items":{"type":"string"},"description":"Ask these verbatim instead of the default set."},"callback_url":{"type":"string"}}},"example":{"category":"physiotherapy","region":"Northern Beaches, Sydney","brand":"Northline Physio"}}}}}},"/v1/runs/{id}":{"get":{"summary":"Get a run","description":"Status, and when the run is done the structured result and a pdf_url.","operationId":"get_v1_runs_id_","responses":{"200":{"description":"The run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such run on this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]}},"/v1/runs":{"get":{"summary":"List runs","description":"This account's runs, newest first.","operationId":"get_v1_runs","responses":{"200":{"description":"Runs, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/Run"}}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/account":{"get":{"summary":"Get the account","description":"Plan, credits remaining, and usage to date.","operationId":"get_v1_account","responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"plan":{"type":"string"},"credits_remaining":{"type":"number"},"currency":{"type":"string"},"runs_total":{"type":"number"},"key_prefix":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/checkout":{"post":{"summary":"Start a checkout","description":"Creates a Stripe Checkout session for a credit pack, a plan, or the Marketing Diagnosis.","operationId":"post_v1_checkout","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"pack":{"type":"number","description":"One of 100, 250, 500."},"plan":{"type":"string","description":"One of builder, studio."},"product":{"type":"string","description":"Set to \"diagnosis\" to buy the full Marketing Diagnosis."},"email":{"type":"string"},"website":{"type":"string"}}},"example":{"pack":100}}}}}},"/v1/signup":{"post":{"summary":"Sign up","description":"Emails a magic link. Clicking it creates a keyless, zero-credit account and sends you to pricing. A key is minted only after a payment.","operationId":"post_v1_signup","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string"}}},"example":{"email":"you@example.com"}}}}}}}}