{"openapi":"3.1.0","info":{"title":"Unfunnel API","version":"1","summary":"Create, edit, publish and measure mobile landing pages and quiz funnels for paid ads.","description":"Everything a funnel is lives in one JSON document, and the API moves that document around: draft it with AI from a prompt and a website, preview it on a phone with a design review, publish it to a link or a custom domain, wire server-side ad tracking, and read leads with the ad that produced each one. The same operations are tools on the Unfunnel MCP server at https://unfunnel.io/api/mcp. Full reference with recipes: https://unfunnel.io/docs/api.md. Plans and limits apply whichever way a call arrives; GET /api/v1/workspace says what the credential's workspace may do.","contact":{"name":"Unfunnel support","email":"support@unfunnel.io","url":"https://unfunnel.io/docs"},"termsOfService":"https://unfunnel.io/terms"},"externalDocs":{"description":"API reference and the funnel document guide","url":"https://unfunnel.io/docs"},"servers":[{"url":"https://unfunnel.io"}],"security":[{"bearer":[]}],"tags":[{"name":"Workspace","description":"The workspace a credential acts on, its plan, limits and usage."},{"name":"Funnels","description":"Create, read, edit, preview and delete funnels."},{"name":"Publishing","description":"Go live, take down, links, versions and rollback."},{"name":"Results","description":"Leads, metrics and test visits."},{"name":"A/B tests","description":"Two to four versions of one live funnel. Growth and up."},{"name":"Domains","description":"Serve a funnel on the customer's own domain. Launch and up."},{"name":"Tracking","description":"Server-side Conversions API keys and Google Ads, write-only. Launch and up."},{"name":"Brand and media","description":"Brand kits read from a website, images, videos and fonts."}],"paths":{"/api/v1/workspace":{"get":{"tags":["Workspace"],"operationId":"getWorkspace","summary":"Workspace, plan, limits and usage","description":"Which workspace the credential acts on, its plan, what the plan includes, and how much of each limit is used. Call it first. A null limit means no limit.","responses":{"200":{"description":"The workspace","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels":{"get":{"tags":["Funnels"],"operationId":"listFunnels","summary":"List funnels","description":"Every funnel in the workspace. `url` is the funnel's own link and `live_url` where it actually answers (its verified custom domain when it has one); both are null while it is not live.","responses":{"200":{"description":"Funnels","content":{"application/json":{"schema":{"type":"object","properties":{"funnels":{"type":"array","items":{"$ref":"#/components/schemas/FunnelSummary"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Funnels"],"operationId":"createFunnel","summary":"Create a funnel","description":"Pass exactly one source: `doc` (a complete document), `template` (a built-in template id), or `prompt` with `website` or `brand_colors` (AI drafts the whole funnel in that brand, one to three minutes). Optionally publish in the same call. The answer carries any open design `fixes`, and for an AI draft its visual check `qa`.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFunnel"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelWrite"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["Funnels"],"operationId":"getFunnel","summary":"Read a funnel","description":"The draft document and, when published, the published document and its version number.","responses":{"200":{"description":"The funnel","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"tags":["Funnels"],"operationId":"updateFunnel","summary":"Update the draft","description":"Replace the draft with `doc`, have AI edit it with `instruction`, lay out the landing page from a `landing` plan, and or rename it. The live version is untouched until you publish.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"doc":{"$ref":"#/components/schemas/FunnelDocument"},"instruction":{"type":"string","description":"A plain-English edit, for example \"make the headline shorter\". Needs AI on the plan."},"landing":{"$ref":"#/components/schemas/LandingPlan"},"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunnelWrite"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Funnels"],"operationId":"deleteFunnel","summary":"Delete a funnel","description":"Deletes the funnel for good, with its versions, sessions, events and leads. A live funnel is refused with a 409 unless force=true. A custom domain that pointed at it is removed too.","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean"},"description":"Delete even while live"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/preview":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["Funnels"],"operationId":"previewFunnel","summary":"Phone screenshots and a design review","description":"Works on drafts. Returns a phone-sized PNG of each page asked for, base64, plus a review computed from the document: palette, type, a WCAG contrast ratio for every text-on-background pair, and findings ranked error, warning, note.","parameters":[{"name":"pages","in":"query","required":false,"schema":{"type":"string"},"description":"`first` (default), `all`, or a comma separated list of page ids, four at most"},{"name":"images","in":"query","required":false,"schema":{"type":"boolean"},"description":"false returns the review alone, instantly"}],"responses":{"200":{"description":"Images and review","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/publish":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"post":{"tags":["Publishing"],"operationId":"publishFunnel","summary":"Publish, republish or roll back","description":"`slug` the first time; afterwards an empty body republishes at the same link. `version` puts an earlier version live again as a new version. Refused with a 422 carrying `fixes` while the draft has a blocking fix, unless `force` is true.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","pattern":"^[a-z0-9-]{2,50}$","description":"The funnel's link, https://<slug>.unfunnel.page. Choosing one is Launch and up."},"force":{"type":"boolean","description":"Publish despite open blocking fixes; written to the audit trail"},"version":{"type":"integer","description":"Restore this version"},"discard_draft":{"type":"boolean","description":"With version: drop unpublished draft edits instead of refusing with 409"}}}}}},"responses":{"200":{"description":"Live","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"url":{"type":"string"},"version":{"type":"integer"},"forced":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Publishing"],"operationId":"unpublishFunnel","summary":"Unpublish","description":"Takes the funnel offline without deleting it. Draft, link, versions, domain, leads and metrics are kept.","responses":{"200":{"description":"Back to draft","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/versions":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["Publishing"],"operationId":"listVersions","summary":"List published versions","description":"Every publish is a numbered version; the list says which one is live.","responses":{"200":{"description":"Versions","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/versions/{version}":{"parameters":[{"$ref":"#/components/parameters/FunnelId"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"Version number"}],"get":{"tags":["Publishing"],"operationId":"getVersion","summary":"Read one version","description":"That version's whole document.","responses":{"200":{"description":"The version","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/slugs/{slug}":{"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The link to check"}],"get":{"tags":["Publishing"],"operationId":"checkSlug","summary":"Is a link available?","description":"Links are unique across Unfunnel. `reason` is one of invalid, reserved, taken or yours. `can_choose` says whether the plan may pick a link (Launch and up).","responses":{"200":{"description":"Availability","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/templates":{"get":{"tags":["Funnels"],"operationId":"listTemplates","summary":"List templates","description":"The built-in templates `POST /api/v1/funnels` accepts as `template`.","responses":{"200":{"description":"Templates","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/leads":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["Results"],"operationId":"getFunnelLeads","summary":"A funnel's leads","description":"Newest first, each with the visitor's answers and the ad attribution that produced it (ad_id, adset_id, campaign_id, UTMs). Pass `next_before` back as `before` for the next page.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Page size"},{"name":"before","in":"query","required":false,"schema":{"type":"string"},"description":"ISO timestamp"}],"responses":{"200":{"description":"Leads","content":{"application/json":{"schema":{"type":"object","properties":{"leads":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"next_before":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/leads":{"get":{"tags":["Results"],"operationId":"listLeads","summary":"Leads across every funnel","description":"`before` pages newest first. `after` returns leads created after a point, oldest first, for a CRM sync: keep `next_after` and pass it next time. Test visits are left out unless test=true, or test=all for both.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Page size, up to 200"},{"name":"before","in":"query","required":false,"schema":{"type":"string"},"description":"ISO timestamp"},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"ISO timestamp"},{"name":"funnel_id","in":"query","required":false,"schema":{"type":"string"},"description":"Only this funnel"},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/LeadStatus"},"description":"Only this status"},{"name":"test","in":"query","required":false,"schema":{"type":"string","enum":["true","all"]},"description":"true for test leads only, all for both"}],"responses":{"200":{"description":"Leads","content":{"application/json":{"schema":{"type":"object","properties":{"leads":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/leads/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Lead id"}],"get":{"tags":["Results"],"operationId":"getLead","summary":"Read a lead","description":"One lead with its answers and attribution.","responses":{"200":{"description":"The lead","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"tags":["Results"],"operationId":"updateLead","summary":"Set a lead's status or notes","description":"So a CRM can write its outcome back.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/LeadStatus"},"notes":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Results"],"operationId":"deleteLead","summary":"Delete a lead","description":"Permanent, and written to the workspace's audit trail.","responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/metrics":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["Results"],"operationId":"getMetrics","summary":"The funnel's report","description":"The Metrics page as data: sessions, leads, qualified, conversion, drop-off per step, platforms, creatives (cost per lead by ad), campaigns, sources, time on page, devices and answer counts.","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"string"},"description":"Window in days (default 30, up to a year) or `all`"}],"responses":{"200":{"description":"Report","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Results"],"operationId":"clearMetrics","summary":"Clear recorded traffic","description":"Erases this funnel's sessions and page events, for a funnel walked through during testing. Contacts go too only with contacts=true. Not reversible.","parameters":[{"name":"contacts","in":"query","required":false,"schema":{"type":"boolean"},"description":"Also delete captured leads"}],"responses":{"200":{"description":"Cleared","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/test-link":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"post":{"tags":["Results"],"operationId":"createTestLink","summary":"A test-visit link","description":"Opens the live funnel as a test visit for 24 hours: kept out of reports, server events go to each platform's test channel, and the lead fires no webhook unless sendLeads is true.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"metaTestCode":{"type":"string"},"sendLeads":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Link","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"url":{"type":"string"},"expiresAt":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/ab-test":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["A/B tests"],"operationId":"getAbTest","summary":"The open test with results","description":"The open test, else the last to end, with each version's visitors, leads, conversion rate, Bayesian chance to beat the original and a plain-English verdict.","parameters":[{"name":"docs","in":"query","required":false,"schema":{"type":"string","enum":["a","b","c","d"]},"description":"Also return this version's draft and live documents"}],"responses":{"200":{"description":"Test","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["A/B tests"],"operationId":"createAbTest","summary":"Set up a test","description":"Makes versions B to D as copies of the live page with an even split. Nothing is served until it is set running.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"versions":{"type":"integer","minimum":2,"maximum":4}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"tags":["A/B tests"],"operationId":"updateAbTest","summary":"Change a test","description":"Applied in order, stopping at the first refusal: add_variant, docs (version drafts), weights, publish, status.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"add_variant":{"type":"boolean"},"docs":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/FunnelDocument"}},"weights":{"type":"object","additionalProperties":{"type":"number","minimum":0,"maximum":100}},"publish":{"oneOf":[{"type":"boolean"},{"type":"array","items":{"type":"string"}}]},"status":{"type":"string","enum":["running","paused"]}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["A/B tests"],"operationId":"endAbTest","summary":"End without a winner","description":"The live page is untouched.","responses":{"200":{"description":"Ended","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/ab-test/winner":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"post":{"tags":["A/B tests"],"operationId":"pickAbTestWinner","summary":"Make a version the live funnel","description":"Publishes the winning version as a new version of the funnel and ends the test. `a` keeps the original.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["variant"],"properties":{"variant":{"type":"string","enum":["a","b","c","d"]}}}}}},"responses":{"200":{"description":"Winner live","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/domains":{"get":{"tags":["Domains"],"operationId":"listDomains","summary":"List custom domains","description":"The workspace's domains and their status.","responses":{"200":{"description":"Domains","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Domains"],"operationId":"connectDomain","summary":"Connect a domain","description":"Saves the mapping and answers `dns`, the records to create at the domain's DNS provider, then call verify. A hostname showing another of the workspace's funnels is a 409 unless move is true.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hostname","funnel_id"],"properties":{"hostname":{"type":"string"},"funnel_id":{"type":"string"},"move":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Connected","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/domains/{hostname}":{"parameters":[{"name":"hostname","in":"path","required":true,"schema":{"type":"string"},"description":"For example quiz.brand.com"}],"get":{"tags":["Domains"],"operationId":"getDomain","summary":"Read a domain","description":"Its funnel, status and DNS records.","responses":{"200":{"description":"Domain","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Domains"],"operationId":"removeDomain","summary":"Disconnect a domain","description":"The funnel keeps its unfunnel.page link; the domain stops answering.","responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/domains/{hostname}/verify":{"parameters":[{"name":"hostname","in":"path","required":true,"schema":{"type":"string"},"description":"For example quiz.brand.com"}],"post":{"tags":["Domains"],"operationId":"verifyDomain","summary":"Check the DNS now","description":"Answers `verified`, and while false, `missing` says what is still wrong. Polling every minute or two is fine.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Verification","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/tracking":{"parameters":[{"$ref":"#/components/parameters/FunnelId"}],"get":{"tags":["Tracking"],"operationId":"getTracking","summary":"Tracking setup and recent deliveries","description":"What is set for Meta, ChatGPT Ads and Google Ads (secrets only as their last four characters), and the last server events with each platform's reply.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"How many deliveries"}],"responses":{"200":{"description":"Tracking","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/tracking/{platform}":{"parameters":[{"$ref":"#/components/parameters/FunnelId"},{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["meta","openai","google"]},"description":"meta, openai or google"}],"put":{"tags":["Tracking"],"operationId":"setTracking","summary":"Store a server-side key, or choose the Google Ads account","description":"meta: access_token (dataset_id defaults to the document's pixel). openai: api_key (pixel_id defaults to the document's). google: customer_id, after the Google sign-in, creates a conversion action per category. Stored encrypted and never returned.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"dataset_id":{"type":"string"},"api_key":{"type":"string"},"pixel_id":{"type":"string"},"customer_id":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}},"delete":{"tags":["Tracking"],"operationId":"removeTracking","summary":"Remove a platform's server-side connection","description":"The browser pixel in the document is unaffected.","responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/funnels/{id}/tracking/{platform}/connect":{"parameters":[{"$ref":"#/components/parameters/FunnelId"},{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["google"]},"description":"google"}],"post":{"tags":["Tracking"],"operationId":"connectGoogleAds","summary":"Start the Google Ads sign-in","description":"Answers a sign-in `url`, good for 15 minutes, for the key's owner to open in a browser where they are signed in to Unfunnel.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Sign-in link","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/webhooks/secret":{"get":{"tags":["Tracking"],"operationId":"getWebhookSecret","summary":"The webhook signing secret","description":"Lead and completion webhooks carry X-Unfunnel-Signature: t=<unix>,v1=<hex HMAC-SHA256 of `<t>.<raw body>`> keyed with this secret. One per workspace.","responses":{"200":{"description":"Secret","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/brand":{"get":{"tags":["Brand and media"],"operationId":"getBrandKit","summary":"The workspace's brand kit","description":"The logo, colours and fonts last read from the brand's website.","responses":{"200":{"description":"Brand kit","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Brand and media"],"operationId":"brandFromUrl","summary":"Read a website into a brand kit","description":"Reads the site with a real browser for its logo, colours and fonts, and answers a contrast-checked funnel theme built from them.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"refresh":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Brand kit and theme","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/media":{"get":{"tags":["Brand and media"],"operationId":"listMedia","summary":"The media library","description":"Images by default; kind=video or kind=font for those.","parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["image","video","font"]},"description":"What to list"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Up to 200"}],"responses":{"200":{"description":"Library","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Brand and media"],"operationId":"uploadMedia","summary":"Add an image, video or font","description":"Exactly one source: `url` to copy something online (preferred), `data` as base64, or a multipart upload with the file in a field named file (videos). The answer's url goes straight into a document.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"data":{"type":"string","description":"Base64 bytes or a data: URI"},"content_type":{"type":"string"},"kind":{"type":"string","enum":["image","video","font"]},"filename":{"type":"string"},"family":{"type":"string"},"weight":{"type":"integer"},"style":{"type":"string"}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"kind":{"type":"string"}}}}}},"responses":{"200":{"description":"Already in the library","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Uploaded","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/media/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Media id"}],"delete":{"tags":["Brand and media"],"operationId":"deleteMedia","summary":"Delete a file","description":"Removes the object and its row. Nothing checks whether a funnel still points at it.","responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/media/uploads":{"post":{"tags":["Brand and media"],"operationId":"getUploadUrl","summary":"An upload link for a local file","description":"PUT the file's bytes to the returned upload_url with that Content-Type, then call /api/v1/media/uploads/complete. Good for two hours.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["filename","content_type"],"properties":{"filename":{"type":"string"},"content_type":{"type":"string"}}}}}},"responses":{"200":{"description":"Upload link","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/media/uploads/complete":{"post":{"tags":["Brand and media"],"operationId":"finishUpload","summary":"Finish an upload","description":"Checks what arrived and adds it to the library; returns its url, and poster_url for a video.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["path"],"properties":{"path":{"type":"string"}}}}}},"responses":{"200":{"description":"Added","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key (tl_live_..., made in the app under the menu, API; Growth and up) or an OAuth access token from the MCP connector sign-in. Discovery: https://unfunnel.io/.well-known/oauth-protected-resource."}},"parameters":{"FunnelId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Funnel id"},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"Repeat a POST with the same key within a day and the first answer comes back instead of a second funnel or a second AI charge."}},"responses":{"BadRequest":{"description":"Bad input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing, invalid or revoked credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PaymentRequired":{"description":"The workspace's plan does not include this; `upgrade` is true","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Your seat in the workspace does not allow it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Not in this workspace, or not there","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Conflicts with the current state, for example a live funnel or a domain in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"The document or request failed validation; the message names the path","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limited. Wait the Retry-After seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"upgrade":{"type":"boolean"},"retry_after":{"type":"integer"},"fixes":{"type":"array","items":{"$ref":"#/components/schemas/Fix"}}}},"Fix":{"type":"object","description":"A change the page still needs. A blocking fix holds up publishing unless forced.","properties":{"path":{"type":"string"},"problem":{"type":"string"},"fix":{"type":"string"},"blocking":{"type":"boolean"}}},"FunnelSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published"]},"url":{"type":["string","null"]},"live_url":{"type":["string","null"]},"domain":{"type":["object","null"],"properties":{"hostname":{"type":"string"},"verified":{"type":"boolean"}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FunnelWrite":{"type":"object","properties":{"funnel":{"$ref":"#/components/schemas/FunnelSummary"},"fixes":{"type":"array","items":{"$ref":"#/components/schemas/Fix"}},"qa":{"type":"object","description":"AI runs only: the visual check","properties":{"passed":{"type":"boolean"},"revisions":{"type":"integer"},"issues":{"type":"array","items":{"type":"string"}}}},"publish_error":{"type":"string"}}},"CreateFunnel":{"type":"object","description":"Exactly one of doc, template or prompt.","properties":{"doc":{"$ref":"#/components/schemas/FunnelDocument"},"template":{"type":"string","description":"A template id from GET /api/v1/templates, for example lead-magnet"},"prompt":{"type":"string","description":"What the funnel is for; AI drafts every page. Needs website or brand_colors."},"website":{"type":"string","format":"uri","description":"The brand's site, read for its logo, colours and fonts"},"brand_colors":{"type":"object","properties":{"accent":{"type":"string"},"ground":{"type":"string"},"ink":{"type":"string"},"logo_url":{"type":"string"}}},"landing":{"$ref":"#/components/schemas/LandingPlan"},"name":{"type":"string"},"model":{"type":"string","description":"Model for a prompt; default Sonnet"},"publish":{"type":"object","properties":{"slug":{"type":"string"},"force":{"type":"boolean"}}}}},"LandingPlan":{"type":"object","description":"The landing page as a plan of words (headline, offer, button, proof, sections), laid out by Unfunnel. See /docs/funnel-document.md."},"LeadStatus":{"type":"string","enum":["new","contacted","qualified","won","lost"]},"Lead":{"type":"object","properties":{"id":{"type":"string"},"funnel_id":{"type":"string"},"funnel_name":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"answers":{"type":"object"},"score":{"type":["number","null"]},"qualified":{"type":["boolean","null"]},"status":{"$ref":"#/components/schemas/LeadStatus"},"notes":{"type":["string","null"]},"test":{"type":"boolean"},"attribution":{"type":["object","null"],"description":"The ad that produced the lead, captured on landing","properties":{"ad_id":{"type":["string","null"]},"adset_id":{"type":["string","null"]},"campaign_id":{"type":["string","null"]},"utm_source":{"type":["string","null"]},"utm_medium":{"type":["string","null"]},"utm_campaign":{"type":["string","null"]},"utm_content":{"type":["string","null"]},"utm_term":{"type":["string","null"]},"placement":{"type":["string","null"]},"referrer":{"type":["string","null"]}}}}},"FunnelDocument":{"type":"object","properties":{"schemaVersion":{"type":"number","const":2},"name":{"type":"string","minLength":1},"brand":{"type":"object","properties":{"name":{"type":"string","minLength":1},"logoUrl":{"type":"string"},"website":{"type":"string","maxLength":500,"format":"uri"},"logoWithName":{"type":"boolean"},"logoPosition":{"default":"left","type":"string","enum":["left","center"]},"logoSize":{"type":"string","enum":["sm","md","lg"]},"logoLink":{"type":"string","maxLength":500,"format":"uri"},"footer":{"type":"string"},"legal":{"type":"string"}},"required":["name"]},"meta":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"image":{"type":"string","format":"uri"},"favicon":{"type":"string","format":"uri"},"adHooks":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}}},"required":["title","description"]},"theme":{"type":"object","properties":{"ground":{"type":"string","minLength":2},"surface":{"type":"string","minLength":2},"surfaceHi":{"type":"string","minLength":2},"ink":{"type":"string","minLength":2},"inkMuted":{"type":"string","minLength":2},"line":{"type":"string","minLength":2},"accent":{"type":"string","minLength":2},"accentInk":{"type":"string","minLength":2},"accentAlt":{"type":"string","minLength":2},"gradient":{"type":"object","properties":{"stops":{"minItems":2,"maxItems":4,"type":"array","items":{"type":"string","minLength":2}},"angle":{"default":90,"type":"integer","minimum":0,"maximum":360},"ink":{"type":"string","minLength":2},"rules":{"type":"boolean"},"progress":{"type":"boolean"}},"required":["stops"]},"radius":{"default":"lg","type":"string","enum":["sm","md","lg","xl"]},"look":{"type":"string","enum":["clean","bold","editorial"]},"style":{"type":"string","enum":["classic","soft","app"]},"backdrop":{"type":"string","enum":["flat","glow"]},"optionStyle":{"default":"card","type":"string","enum":["card","filled"]},"button":{"default":{"shape":"rounded","caps":false},"type":"object","properties":{"shape":{"default":"rounded","type":"string","enum":["pill","rounded"]},"caps":{"default":false,"type":"boolean"}}},"fonts":{"default":{"display":"Instrument Sans","body":"Instrument Sans","displayWeight":700,"extra":[]},"type":"object","properties":{"display":{"default":"Instrument Sans","type":"string"},"body":{"default":"Instrument Sans","type":"string"},"displayWeight":{"default":700,"type":"integer","minimum":300,"maximum":900},"extra":{"default":[],"maxItems":4,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9-]{1,24}$"},"family":{"type":"string","minLength":1},"weight":{"default":400,"type":"integer","minimum":100,"maximum":900}},"required":["id","family"]}},"custom":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9-]{1,24}$"},"family":{"type":"string","pattern":"^[A-Za-z0-9 ._-]{1,60}$"},"url":{"type":"string","maxLength":500,"pattern":"^https?:\\/\\/[^\\s\"'()\\\\<>;]+$"},"weight":{"default":400,"type":"integer","minimum":100,"maximum":900},"style":{"default":"normal","type":"string","enum":["normal","italic"]},"format":{"type":"string","enum":["woff2","woff","truetype","opentype"]}},"required":["family","url"]}},"brandFaces":{"type":"object","properties":{"display":{"type":"string","maxLength":80},"body":{"type":"string","maxLength":80}}}}},"emphasis":{"type":"object","properties":{"font":{"type":"string"},"color":{"default":"accent","type":"string","enum":["accent","accentAlt","ink","inkMuted","ground","accentInk"]},"italic":{"default":false,"type":"boolean"},"weight":{"type":"integer","minimum":100,"maximum":900},"highlight":{"default":"none","type":"string","enum":["none","accent","accentAlt","surface","surfaceHi"]}}},"typography":{"type":"object","properties":{"heading":{"type":"string"},"body":{"type":"string"},"button":{"type":"string"},"eyebrow":{"type":"string"}}}},"required":["ground","surface","surfaceHi","ink","inkMuted","line","accent","accentInk"]},"settings":{"default":{"progress":"bottom","resumeOnReturn":true},"type":"object","properties":{"progress":{"default":"bottom","type":"string","enum":["top","bottom","none"]},"resumeOnReturn":{"default":true,"type":"boolean"},"webhookUrl":{"type":"string","format":"uri"},"campaignLabel":{"type":"string"},"metaPixelId":{"type":"string","pattern":"^\\d{5,20}$"},"openaiPixelId":{"type":"string","pattern":"^[A-Za-z0-9_-]{6,64}$"},"googleAdsId":{"type":"string","pattern":"^AW-\\d{6,15}$"},"googleConversions":{"type":"object","propertyNames":{"type":"string","enum":["submit_lead_form","book_appointment","qualified_lead","contact","request_quote","sign_up","page_view","outbound_click"]},"additionalProperties":{"type":"string","pattern":"^[A-Za-z0-9_-]{4,64}$"}},"language":{"type":"string","pattern":"^[a-z]{2}(-[A-Za-z]{2,8})?$"},"sendAnswersToMeta":{"type":"boolean"},"metaEvents":{"type":"object","properties":{"landing":{"type":"string","enum":["PageView","ViewContent","Lead","CompleteRegistration","Contact","Schedule","SubmitApplication","Subscribe","StartTrial","InitiateCheckout","AddPaymentInfo","Purchase","Search","FindLocation","CustomizeProduct","Donate","AddToCart","AddToWishlist","off"]},"step":{"type":"string","enum":["PageView","ViewContent","Lead","CompleteRegistration","Contact","Schedule","SubmitApplication","Subscribe","StartTrial","InitiateCheckout","AddPaymentInfo","Purchase","Search","FindLocation","CustomizeProduct","Donate","AddToCart","AddToWishlist","off","custom"]},"lead":{"type":"string","enum":["PageView","ViewContent","Lead","CompleteRegistration","Contact","Schedule","SubmitApplication","Subscribe","StartTrial","InitiateCheckout","AddPaymentInfo","Purchase","Search","FindLocation","CustomizeProduct","Donate","AddToCart","AddToWishlist","off"]},"qualified":{"type":"string","enum":["PageView","ViewContent","Lead","CompleteRegistration","Contact","Schedule","SubmitApplication","Subscribe","StartTrial","InitiateCheckout","AddPaymentInfo","Purchase","Search","FindLocation","CustomizeProduct","Donate","AddToCart","AddToWishlist","off"]},"disqualified":{"type":"string","enum":["PageView","ViewContent","Lead","CompleteRegistration","Contact","Schedule","SubmitApplication","Subscribe","StartTrial","InitiateCheckout","AddPaymentInfo","Purchase","Search","FindLocation","CustomizeProduct","Donate","AddToCart","AddToWishlist","off"]}}},"events":{"type":"object","propertyNames":{"type":"string","enum":["landing","step","lead","booked","qualified","disqualified","click"]},"additionalProperties":{"type":"object","propertyNames":{"type":"string","enum":["meta","openai","google"]},"additionalProperties":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9_]{0,63}$"}}},"webhooks":{"type":"object","properties":{"newLead":{"default":[],"maxItems":3,"type":"array","items":{"type":"string","format":"uri"}},"funnelCompleted":{"default":[],"maxItems":3,"type":"array","items":{"type":"string","format":"uri"}}}},"compliance":{"type":"object","properties":{"cookieBanner":{"default":{"enabled":false,"mode":"notice"},"type":"object","properties":{"enabled":{"default":false,"type":"boolean"},"mode":{"default":"notice","type":"string","enum":["notice","optIn"]},"text":{"type":"string","maxLength":600},"acceptLabel":{"type":"string","maxLength":40},"declineLabel":{"type":"string","maxLength":40}}},"privacyUrl":{"type":"string","format":"uri"},"termsUrl":{"type":"string","format":"uri"},"smsConsent":{"default":{"enabled":false,"required":true},"type":"object","properties":{"enabled":{"default":false,"type":"boolean"},"required":{"default":true,"type":"boolean"},"text":{"type":"string","maxLength":1200}}},"humanCheck":{"type":"object","properties":{"enabled":{"default":false,"type":"boolean"},"placement":{"default":"aboveButton","type":"string","enum":["aboveButton","belowButton","aboveFields"]},"show":{"default":"needed","type":"string","enum":["needed","always"]}}}}}}},"pages":{"minItems":2,"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"layout":{"default":"center","type":"string","enum":["hero","center","top"]},"align":{"default":"center","type":"string","enum":["center","left"]},"decorations":{"default":[],"maxItems":4,"type":"array","items":{"type":"object","properties":{"shape":{"default":"circle","type":"string","enum":["circle","square","blob"]},"color":{"default":"accentAlt","type":"string","enum":["accent","accentAlt","surface","surfaceHi","ink"]},"size":{"default":"lg","type":"string","enum":["sm","md","lg","xl"]},"position":{"default":"top-right","type":"string","enum":["top-left","top-right","bottom-left","bottom-right","center-left","center-right"]},"opacity":{"default":1,"type":"number","minimum":0.05,"maximum":1}}}},"background":{"type":"object","properties":{"imageUrl":{"type":"string"},"overlay":{"default":0.75,"type":"number","minimum":0,"maximum":1}}},"blocks":{"minItems":1,"maxItems":200,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"eyebrow"},"text":{"type":"string"},"emoji":{"type":"string","maxLength":8}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"heading"},"text":{"type":"string"},"size":{"default":"lg","type":"string","enum":["md","lg","xl"]}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"subtext"},"text":{"type":"string"},"size":{"type":"string","enum":["md","lg"]}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"badge"},"text":{"type":"string"},"dot":{"default":true,"type":"boolean"}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"stats"},"items":{"minItems":1,"maxItems":4,"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"},"icon":{"type":"string","enum":["store","fuel","building","building-2","warehouse","factory","hotel","home","landmark","school","map-pin","map","globe","route","signpost","parking","car","truck","bus","plane","user","users","user-plus","handshake","briefcase","key","phone","mail","message-circle","smile","thumbs-up","eye","heart","dollar-sign","banknote","coins","wallet","credit-card","receipt","piggy-bank","percent","trending-up","chart-bar","chart-line","chart-pie","gauge","clock","timer","calendar","hourglass","zap","battery-charging","plug","activity","sun","leaf","flame","droplets","shield-check","shield","check","circle-check","x","star","award","trophy","medal","crown","sparkles","target","rocket","lightbulb","lock","flag","wrench","hammer","hard-hat","ruler","pencil","file-text","clipboard-check","list-checks","settings","layers","package","hash","search","compass","cpu","wifi","camera","video","mic","utensils","coffee","bath","shopping-cart","shopping-bag","gift","ticket","tag","lamp","sofa","dumbbell","stethoscope","graduation-cap","book-open","music","palette","scissors","paw-print","baby","ellipsis","help","info","alert","bell","arrow-right","plus","minus"]}},"required":["value","label"]}}},"required":["type","items"]},{"type":"object","properties":{"type":{"type":"string","const":"image"},"url":{"type":"string"},"alt":{"default":"","type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","const":"video"},"url":{"type":"string"},"poster":{"type":"string"},"aspect":{"type":"string","enum":["16:9","9:16","1:1"]},"autoplay":{"type":"boolean"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","const":"list"},"items":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","items"]},{"type":"object","properties":{"type":{"type":"string","const":"testimonial"},"quote":{"type":"string"},"name":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5}},"required":["type","quote","name"]},{"type":"object","properties":{"type":{"type":"string","const":"chart"},"trend":{"default":"rise","type":"string","enum":["rise","fall"]},"from":{"type":"string","minLength":1,"maxLength":40},"to":{"type":"string","minLength":1,"maxLength":40},"marker":{"type":"string","maxLength":30},"caption":{"type":"string","maxLength":200}},"required":["type","from","to"]},{"type":"object","properties":{"type":{"type":"string","const":"quote"},"text":{"type":"string"},"attribution":{"type":"string"}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"features"},"layout":{"default":"cards","type":"string","enum":["cards","list","steps"]},"items":{"minItems":1,"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"icon":{"type":"string","enum":["store","fuel","building","building-2","warehouse","factory","hotel","home","landmark","school","map-pin","map","globe","route","signpost","parking","car","truck","bus","plane","user","users","user-plus","handshake","briefcase","key","phone","mail","message-circle","smile","thumbs-up","eye","heart","dollar-sign","banknote","coins","wallet","credit-card","receipt","piggy-bank","percent","trending-up","chart-bar","chart-line","chart-pie","gauge","clock","timer","calendar","hourglass","zap","battery-charging","plug","activity","sun","leaf","flame","droplets","shield-check","shield","check","circle-check","x","star","award","trophy","medal","crown","sparkles","target","rocket","lightbulb","lock","flag","wrench","hammer","hard-hat","ruler","pencil","file-text","clipboard-check","list-checks","settings","layers","package","hash","search","compass","cpu","wifi","camera","video","mic","utensils","coffee","bath","shopping-cart","shopping-bag","gift","ticket","tag","lamp","sofa","dumbbell","stethoscope","graduation-cap","book-open","music","palette","scissors","paw-print","baby","ellipsis","help","info","alert","bell","arrow-right","plus","minus"]},"title":{"type":"string"},"text":{"type":"string"}},"required":["title","text"]}}},"required":["type","items"]},{"type":"object","properties":{"type":{"type":"string","const":"logos"},"heading":{"type":"string"},"items":{"minItems":2,"maxItems":24,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1},"imageUrl":{"type":"string"}},"required":["name"]}},"marquee":{"default":true,"type":"boolean"},"tone":{"type":"string","enum":["ink","paper"]}},"required":["type","items"]},{"type":"object","properties":{"type":{"type":"string","const":"faq"},"items":{"minItems":1,"maxItems":12,"type":"array","items":{"type":"object","properties":{"q":{"type":"string","minLength":1},"a":{"type":"string","minLength":1}},"required":["q","a"]}}},"required":["type","items"]},{"type":"object","properties":{"type":{"type":"string","const":"spacer"},"size":{"default":"md","type":"string","enum":["xs","sm","md","lg","xl"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"divider"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"legal"},"text":{"type":"string"}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","const":"section"},"tone":{"default":"surface","type":"string","enum":["ink","accent","surface","surfaceHi","ground"]},"fill":{"default":"flat","type":"string","enum":["flat","gradient","glow","wash"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"choice"},"field":{"type":"string","minLength":1},"variant":{"default":"list","type":"string","enum":["list","grid"]},"multiple":{"default":false,"type":"boolean"},"advanceOnSelect":{"default":true,"type":"boolean"},"submitLabel":{"default":"Continue","type":"string"},"options":{"minItems":2,"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"},"sublabel":{"type":"string"},"emoji":{"type":"string"},"imageUrl":{"type":"string"},"icon":{"type":"string","enum":["store","fuel","building","building-2","warehouse","factory","hotel","home","landmark","school","map-pin","map","globe","route","signpost","parking","car","truck","bus","plane","user","users","user-plus","handshake","briefcase","key","phone","mail","message-circle","smile","thumbs-up","eye","heart","dollar-sign","banknote","coins","wallet","credit-card","receipt","piggy-bank","percent","trending-up","chart-bar","chart-line","chart-pie","gauge","clock","timer","calendar","hourglass","zap","battery-charging","plug","activity","sun","leaf","flame","droplets","shield-check","shield","check","circle-check","x","star","award","trophy","medal","crown","sparkles","target","rocket","lightbulb","lock","flag","wrench","hammer","hard-hat","ruler","pencil","file-text","clipboard-check","list-checks","settings","layers","package","hash","search","compass","cpu","wifi","camera","video","mic","utensils","coffee","bath","shopping-cart","shopping-bag","gift","ticket","tag","lamp","sofa","dumbbell","stethoscope","graduation-cap","book-open","music","palette","scissors","paw-print","baby","ellipsis","help","info","alert","bell","arrow-right","plus","minus"]},"score":{"default":0,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tally":{"type":"string","pattern":"^[a-z0-9_-]{1,40}$"},"tallyWeight":{"type":"integer","minimum":1,"maximum":9}},"required":["value","label"]}}},"required":["type","field","options"]},{"type":"object","properties":{"type":{"type":"string","const":"form"},"fields":{"minItems":1,"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1},"kind":{"type":"string","enum":["text","email","tel","number","name","url"]},"placeholder":{"type":"string"},"emoji":{"type":"string"},"required":{"default":true,"type":"boolean"}},"required":["field","kind","placeholder"]}},"consent":{"type":"object","properties":{"field":{"default":"sms_consent","type":"string"},"text":{"type":"string"},"required":{"default":true,"type":"boolean"}},"required":["text"]},"submit":{"type":"object","properties":{"label":{"type":"string"},"loadingLabel":{"default":"Sending...","type":"string"},"note":{"type":"string"}},"required":["label"]},"action":{"default":"lead","type":"string","enum":["lead","continue"]},"leadEvent":{"type":"boolean"},"skip":{"type":"object","properties":{"label":{"type":"string"},"field":{"type":"string"},"storeValue":{"type":"string"}},"required":["label","field","storeValue"]}},"required":["type","fields","submit"]},{"type":"object","properties":{"type":{"type":"string","const":"cta"},"label":{"type":"string"},"note":{"type":"string"},"style":{"default":"primary","type":"string","enum":["primary","ghost","gradient"]},"action":{"default":"next","type":"string","enum":["next"]},"href":{"type":"string"},"passParams":{"type":"boolean"},"event":{"type":"string","pattern":"^(off|[A-Za-z][A-Za-z0-9_]{0,39})$"}},"required":["type","label"]},{"type":"object","properties":{"type":{"type":"string","const":"embed"},"provider":{"default":"custom","type":"string","enum":["custom","calendly","cal","ghl"]},"url":{"type":"string","format":"uri"},"prefill":{"default":[],"type":"array","items":{"type":"string"}},"height":{"default":600,"type":"integer","minimum":200,"maximum":2000}},"required":["type","url"]}]}},"hero":{"type":"string","enum":["auto","split","stacked"]},"autoAdvance":{"type":"object","properties":{"afterMs":{"type":"integer","minimum":300,"maximum":30000}},"required":["afterMs"]},"outcome":{"type":"string","enum":["qualified","disqualified"]},"next":{"type":"object","properties":{"rules":{"default":[],"type":"array","items":{"type":"object","properties":{"when":{"type":"object","properties":{"field":{"type":"string"},"op":{"type":"string","enum":["eq","neq","in","notIn","gt","lt","contains","scoreGte","tallyMax"]},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"array","items":{"type":"string"}}]}},"required":["field","op","value"]},"goto":{"type":"string"}},"required":["when","goto"]}},"default":{"type":"string"}},"required":["default"]},"event":{"type":"string","pattern":"^(off|[A-Za-z][A-Za-z0-9_]{0,39})$"}},"required":["id","blocks"]}}},"required":["schemaVersion","name","brand","meta","theme","pages"],"description":"A whole funnel: brand, meta, theme, settings and pages made of blocks. The guide is /docs/funnel-document.md. Keys the format does not have are refused with a 422 naming the path, never silently dropped."}}}}