{
  "openapi": "3.1.0",
  "info": {
    "title": "Rig public web API",
    "version": "1.0.0",
    "summary": "Read Rig's public site content as JSON, and submit the forms rig.so serves.",
    "description": "Everything on rig.so that an agent can call without credentials.\n\nTwo groups of endpoints:\n\n- **Content** (`/api/v1/*`): the site's own pages, guides, case studies, integrations and app gallery as JSON. Read-only, unauthenticated, CORS-open, and regenerated on every deploy. Each entry carries a `markdownUrl`; every page on rig.so is also served as markdown when the request sends `Accept: text/markdown`.\n- **Forms** (`/api/forms/*`): one endpoint per public form (demo, signup, events, contact, survey). Public writes, protected by risk scoring rather than a key. The four lead forms require an address; the survey does not, and deliberately accepts agent submissions. See `/survey-agent.md`.\n\nThe Rig **product** API and the Rig **MCP** server are a different surface: they act on your own warehouse, need a Rig account, and live on app.rig.so. Connect over MCP (Streamable HTTP) at `https://app.rig.so/mcp/{workspace}/`; the manifest is at `/.well-known/mcp.json`.\n\nErrors are always JSON, with a stable `error.code`, a human-readable `error.message`, and a `error.hint` saying what to do next.",
    "termsOfService": "https://rig.so/terms",
    "contact": {
      "name": "Rig",
      "url": "https://rig.so/contact"
    },
    "license": {
      "name": "Content is Rig's, free to read, quote and cite with attribution",
      "url": "https://rig.so/terms"
    }
  },
  "servers": [
    {
      "url": "https://rig.so",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Developer portal",
    "url": "https://rig.so/developers"
  },
  "tags": [
    {
      "name": "content",
      "description": "Read-only JSON mirrors of the public site."
    },
    {
      "name": "forms",
      "description": "Public form submission endpoints."
    },
    {
      "name": "discovery",
      "description": "Machine-readable descriptions of this site and of Rig's MCP server."
    }
  ],
  "paths": {
    "/api/v1/index.json": {
      "get": {
        "operationId": "getApiIndex",
        "summary": "API index",
        "description": "Entry point. Lists every content endpoint with a one-line description, plus links to the OpenAPI document, the MCP manifest, llms.txt and the sitemap. Start here if you are discovering the API.",
        "tags": [
          "discovery"
        ],
        "responses": {
          "200": {
            "description": "The index document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/site.json": {
      "get": {
        "operationId": "getSiteProfile",
        "summary": "Company and product profile",
        "description": "Who Rig is, what the product does, how to contact the company, and where its documented surfaces live (MCP server, guides, security page). Use this to answer factual questions about Rig without scraping pages.",
        "tags": [
          "discovery"
        ],
        "responses": {
          "200": {
            "description": "The site profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteProfile"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/pages.json": {
      "get": {
        "operationId": "listPages",
        "summary": "Every indexable page",
        "description": "Every page rig.so publishes for indexing, with its title, description, canonical URL and markdown URL. The same set as sitemap.xml, with the metadata attached.",
        "tags": [
          "content"
        ],
        "responses": {
          "200": {
            "description": "Every indexable page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageList"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/guides.json": {
      "get": {
        "operationId": "listGuides",
        "summary": "Product guides and playbooks",
        "description": "The /guides library: setup walkthroughs, connector guides and playbooks, each with its published and last-modified dates where known.",
        "tags": [
          "content"
        ],
        "responses": {
          "200": {
            "description": "Product guides and playbooks",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuideList"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/case-studies.json": {
      "get": {
        "operationId": "listCaseStudies",
        "summary": "Customer case studies",
        "description": "Published customer stories, with the customer name and industry where stated on the page.",
        "tags": [
          "content"
        ],
        "responses": {
          "200": {
            "description": "Customer case studies",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseStudyList"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/integrations.json": {
      "get": {
        "operationId": "listIntegrations",
        "summary": "Supported integrations",
        "description": "Every system Rig connects to (warehouses, CRMs, support desks, product analytics, finance tools), with the page describing that connector.",
        "tags": [
          "content"
        ],
        "responses": {
          "200": {
            "description": "Supported integrations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationList"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/apps.json": {
      "get": {
        "operationId": "listApps",
        "summary": "Data app gallery",
        "description": "The published gallery of data apps teams build on Rig, with the page describing each one.",
        "tags": [
          "content"
        ],
        "responses": {
          "200": {
            "description": "Data app gallery",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppList"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/forms/book-demo": {
      "post": {
        "operationId": "submitBookDemo",
        "summary": "Request a product demo",
        "description": "Books a demo with the Rig team. Requires `email`; `name`, `company` and `use_case` are read by whoever picks it up but are not mandatory.\n\nHuman submissions carry a reCAPTCHA Enterprise token in `captcha_token`. Agents cannot mint one and should omit it: on `survey` a tokenless submission is accepted and tagged `unverified`, which is the supported agent path (see `/survey-agent.md` and `/survey-spec.json`). On the lead forms a tokenless submission returns 200 with `challenge: true`, meaning a human needs to finish it in a browser.",
        "tags": [
          "forms"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadFormSubmission"
              },
              "examples": {
                "book-demo": {
                  "summary": "Demo request",
                  "value": {
                    "email": "someone@example.com",
                    "name": "Sam Rivers",
                    "company": "Example Ltd"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted, or a step-up. `ok: true` means the submission was forwarded. `ok: false` with `challenge: true` means a human must complete a checkbox in the browser; nothing was stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/VerificationFailed"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamError"
          }
        }
      }
    },
    "/api/forms/signup": {
      "post": {
        "operationId": "submitSignup",
        "summary": "Ask for an account",
        "description": "Registers interest in a Rig workspace. Requires `email`.\n\nHuman submissions carry a reCAPTCHA Enterprise token in `captcha_token`. Agents cannot mint one and should omit it: on `survey` a tokenless submission is accepted and tagged `unverified`, which is the supported agent path (see `/survey-agent.md` and `/survey-spec.json`). On the lead forms a tokenless submission returns 200 with `challenge: true`, meaning a human needs to finish it in a browser.",
        "tags": [
          "forms"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadFormSubmission"
              },
              "examples": {
                "signup": {
                  "summary": "Account request",
                  "value": {
                    "email": "someone@example.com",
                    "company": "Example Ltd"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted, or a step-up. `ok: true` means the submission was forwarded. `ok: false` with `challenge: true` means a human must complete a checkbox in the browser; nothing was stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/VerificationFailed"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamError"
          }
        }
      }
    },
    "/api/forms/events": {
      "post": {
        "operationId": "submitEventsSubscribe",
        "summary": "Subscribe to event announcements",
        "description": "Subscribes an address to announcements of Rig events and recordings. Requires `email`, and nothing else.\n\nHuman submissions carry a reCAPTCHA Enterprise token in `captcha_token`. Agents cannot mint one and should omit it: on `survey` a tokenless submission is accepted and tagged `unverified`, which is the supported agent path (see `/survey-agent.md` and `/survey-spec.json`). On the lead forms a tokenless submission returns 200 with `challenge: true`, meaning a human needs to finish it in a browser.",
        "tags": [
          "forms"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadFormSubmission"
              },
              "examples": {
                "events": {
                  "summary": "Event subscription",
                  "value": {
                    "email": "someone@example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted, or a step-up. `ok: true` means the submission was forwarded. `ok: false` with `challenge: true` means a human must complete a checkbox in the browser; nothing was stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/VerificationFailed"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamError"
          }
        }
      }
    },
    "/api/forms/contact": {
      "post": {
        "operationId": "submitContact",
        "summary": "Write to the Rig team",
        "description": "The written route to Rig, and the only one: no email address is published anywhere on the site. Requires `email` and expects a `message`. Delivered to an internal inbox, with replies going to the address supplied.\n\nHuman submissions carry a reCAPTCHA Enterprise token in `captcha_token`. Agents cannot mint one and should omit it: on `survey` a tokenless submission is accepted and tagged `unverified`, which is the supported agent path (see `/survey-agent.md` and `/survey-spec.json`). On the lead forms a tokenless submission returns 200 with `challenge: true`, meaning a human needs to finish it in a browser.",
        "tags": [
          "forms"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadFormSubmission"
              },
              "examples": {
                "contact": {
                  "summary": "Contact enquiry",
                  "value": {
                    "email": "someone@example.com",
                    "name": "Sam Rivers",
                    "company": "Example Ltd",
                    "message": "We are on Snowflake and want to see the context layer."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted, or a step-up. `ok: true` means the submission was forwarded. `ok: false` with `challenge: true` means a human must complete a checkbox in the browser; nothing was stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/VerificationFailed"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamError"
          }
        }
      }
    },
    "/api/forms/survey": {
      "post": {
        "operationId": "submitSurvey",
        "summary": "Answer the state-of-AI-data survey",
        "description": "The published survey, which is deliberately agent-fillable. No address is required: answering anonymously is supported, and `contact_email` is how you ask to be sent the report. See `/survey-agent.md` for the question set.\n\nHuman submissions carry a reCAPTCHA Enterprise token in `captcha_token`. Agents cannot mint one and should omit it: on `survey` a tokenless submission is accepted and tagged `unverified`, which is the supported agent path (see `/survey-agent.md` and `/survey-spec.json`). On the lead forms a tokenless submission returns 200 with `challenge: true`, meaning a human needs to finish it in a browser.",
        "tags": [
          "forms"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SurveySubmission"
              },
              "examples": {
                "survey": {
                  "summary": "Agent-filled survey response",
                  "value": {
                    "contact_email": "someone@example.com",
                    "q_agents_in_production": "yes_several",
                    "q_data_foundation_ready": "partly"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted, or a step-up. `ok: true` means the submission was forwarded. `ok: false` with `challenge: true` means a human must complete a checkbox in the browser; nothing was stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/VerificationFailed"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamError"
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "NotFound": {
        "description": "No resource exists at that path. (HTTP 404, `error.code: not_found`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "not_found",
                "message": "No resource exists at that path.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "The path exists but not for that method. (HTTP 405, `error.code: method_not_allowed`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "method_not_allowed",
                "message": "The path exists but not for that method.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "InvalidRequest": {
        "description": "The request body was missing, malformed, or failed validation. (HTTP 400, `error.code: invalid_request`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "invalid_request",
                "message": "The request body was missing, malformed, or failed validation.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "The request did not reach the endpoint through an allowed route. Post to rig.so, not to the origin. (HTTP 403, `error.code: forbidden`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "forbidden",
                "message": "The request did not reach the endpoint through an allowed route. Post to rig.so, not to the origin.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The request body exceeded 16 KB. (HTTP 413, `error.code: payload_too_large`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "payload_too_large",
                "message": "The request body exceeded 16 KB.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "VerificationFailed": {
        "description": "The captcha token was invalid, replayed, or minted for another site. (HTTP 422, `error.code: verification_failed`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "verification_failed",
                "message": "The captcha token was invalid, replayed, or minted for another site.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "InternalError": {
        "description": "The endpoint is misconfigured. (HTTP 500, `error.code: internal_error`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "internal_error",
                "message": "The endpoint is misconfigured.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      },
      "UpstreamError": {
        "description": "A downstream system rejected the submission, dropped it, or could not be reached. (HTTP 502, `error.code: upstream_error`)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "ok": false,
              "error": {
                "code": "upstream_error",
                "message": "A downstream system rejected the submission, dropped it, or could not be reached.",
                "hint": "See https://rig.so/developers for the endpoint list.",
                "docs": "https://rig.so/developers"
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Every error response on rig.so has this shape, including the ones generated at the CDN edge for unknown paths.",
        "required": [
          "error"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Always false on an error."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable code. Branch on this, not on the message.",
                "enum": [
                  "not_found",
                  "method_not_allowed",
                  "invalid_request",
                  "payload_too_large",
                  "verification_failed",
                  "forbidden",
                  "internal_error",
                  "upstream_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "What went wrong, in one sentence."
              },
              "hint": {
                "type": "string",
                "description": "What to do about it."
              },
              "docs": {
                "type": "string",
                "format": "uri",
                "description": "Where the endpoint is documented."
              }
            }
          }
        }
      },
      "ApiIndex": {
        "type": "object",
        "required": [
          "object",
          "version",
          "endpoints"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "index"
            ]
          },
          "version": {
            "type": "string",
            "description": "API version, semver."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          },
          "mcp": {
            "type": "string",
            "format": "uri",
            "description": "The MCP manifest."
          },
          "llms": {
            "type": "string",
            "format": "uri"
          },
          "sitemap": {
            "type": "string",
            "format": "uri"
          },
          "endpoints": {
            "type": "array",
            "description": "Every content endpoint, with what it returns.",
            "items": {
              "type": "object",
              "required": [
                "url",
                "operationId",
                "description"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "operationId": {
                  "type": "string",
                  "description": "Matches the operationId in the OpenAPI document."
                },
                "description": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "SiteProfile": {
        "type": "object",
        "required": [
          "object",
          "name",
          "description",
          "url"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "site_profile"
            ]
          },
          "name": {
            "type": "string"
          },
          "legalName": {
            "type": "string"
          },
          "tagline": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "app": {
            "type": "string",
            "format": "uri",
            "description": "Where customers sign in."
          },
          "contact": {
            "type": "object",
            "properties": {
              "contactPage": {
                "type": "string",
                "format": "uri",
                "description": "The human page carrying the form."
              },
              "contactForm": {
                "type": "string",
                "format": "uri",
                "description": "The endpoint that page posts to: POST a LeadFormSubmission here."
              },
              "demo": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "address": {
            "type": "object",
            "properties": {
              "addressLocality": {
                "type": "string"
              },
              "addressRegion": {
                "type": "string"
              },
              "addressCountry": {
                "type": "string",
                "description": "ISO 3166-1 alpha-2."
              }
            }
          },
          "mcp": {
            "type": "object",
            "description": "How an agent connects to the customer's own Rig workspace.",
            "properties": {
              "manifest": {
                "type": "string",
                "format": "uri"
              },
              "transport": {
                "type": "string",
                "enum": [
                  "streamable-http"
                ]
              },
              "urlTemplate": {
                "type": "string"
              },
              "requiresAccount": {
                "type": "boolean"
              },
              "setup": {
                "type": "string",
                "format": "uri",
                "description": "The guide for connecting a client."
              }
            }
          },
          "links": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            },
            "description": "Named links: developers, guides, security, pricing, case studies, sitemap."
          },
          "sameAs": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          }
        }
      },
      "Page": {
        "type": "object",
        "required": [
          "path",
          "url",
          "title",
          "description"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Site-relative path, e.g. /guides/rbac.",
            "example": "/guides/rbac"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute canonical URL."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-paragraph summary of the page."
          },
          "section": {
            "type": "string",
            "description": "Which part of the site the page belongs to.",
            "enum": [
              "pages",
              "guides",
              "case-studies",
              "integrations",
              "apps",
              "use-cases",
              "comparisons",
              "solutions",
              "events"
            ]
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "The same page as markdown. Also served at `url` when the request sends `Accept: text/markdown`."
          }
        }
      },
      "Guide": {
        "type": "object",
        "required": [
          "path",
          "url",
          "title",
          "description"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Site-relative path, e.g. /guides/rbac.",
            "example": "/guides/rbac"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute canonical URL."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-paragraph summary of the page."
          },
          "section": {
            "type": "string",
            "description": "Which part of the site the page belongs to.",
            "enum": [
              "pages",
              "guides",
              "case-studies",
              "integrations",
              "apps",
              "use-cases",
              "comparisons",
              "solutions",
              "events"
            ]
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "The same page as markdown. Also served at `url` when the request sends `Accept: text/markdown`."
          },
          "datePublished": {
            "type": "string",
            "format": "date",
            "description": "First published, where recorded."
          },
          "dateModified": {
            "type": "string",
            "format": "date",
            "description": "Last substantive revision, where recorded."
          }
        }
      },
      "CaseStudy": {
        "type": "object",
        "required": [
          "path",
          "url",
          "title",
          "description"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Site-relative path, e.g. /guides/rbac.",
            "example": "/guides/rbac"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute canonical URL."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-paragraph summary of the page."
          },
          "section": {
            "type": "string",
            "description": "Which part of the site the page belongs to.",
            "enum": [
              "pages",
              "guides",
              "case-studies",
              "integrations",
              "apps",
              "use-cases",
              "comparisons",
              "solutions",
              "events"
            ]
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "The same page as markdown. Also served at `url` when the request sends `Accept: text/markdown`."
          },
          "customer": {
            "type": "string",
            "description": "The customer the story is about."
          },
          "industry": {
            "type": "string",
            "description": "Their industry, where stated."
          }
        }
      },
      "Integration": {
        "type": "object",
        "required": [
          "path",
          "url",
          "title",
          "description"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Site-relative path, e.g. /guides/rbac.",
            "example": "/guides/rbac"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute canonical URL."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-paragraph summary of the page."
          },
          "section": {
            "type": "string",
            "description": "Which part of the site the page belongs to.",
            "enum": [
              "pages",
              "guides",
              "case-studies",
              "integrations",
              "apps",
              "use-cases",
              "comparisons",
              "solutions",
              "events"
            ]
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "The same page as markdown. Also served at `url` when the request sends `Accept: text/markdown`."
          },
          "slug": {
            "type": "string",
            "description": "Stable identifier used in the URL."
          },
          "category": {
            "type": "string",
            "description": "What kind of system it is."
          }
        }
      },
      "App": {
        "type": "object",
        "required": [
          "path",
          "url",
          "title",
          "description"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Site-relative path, e.g. /guides/rbac.",
            "example": "/guides/rbac"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute canonical URL."
          },
          "title": {
            "type": "string",
            "description": "Page title."
          },
          "description": {
            "type": "string",
            "description": "One-paragraph summary of the page."
          },
          "section": {
            "type": "string",
            "description": "Which part of the site the page belongs to.",
            "enum": [
              "pages",
              "guides",
              "case-studies",
              "integrations",
              "apps",
              "use-cases",
              "comparisons",
              "solutions",
              "events"
            ]
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri",
            "description": "The same page as markdown. Also served at `url` when the request sends `Accept: text/markdown`."
          },
          "slug": {
            "type": "string"
          }
        }
      },
      "PageList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ],
            "description": "Always `list` for a collection response."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this document was built."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Page"
            }
          }
        }
      },
      "GuideList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ],
            "description": "Always `list` for a collection response."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this document was built."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Guide"
            }
          }
        }
      },
      "CaseStudyList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ],
            "description": "Always `list` for a collection response."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this document was built."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseStudy"
            }
          }
        }
      },
      "IntegrationList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ],
            "description": "Always `list` for a collection response."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this document was built."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Integration"
            }
          }
        }
      },
      "AppList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ],
            "description": "Always `list` for a collection response."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of items in `data`. The full collection is always returned; there is no pagination."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this document was built."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/App"
            }
          }
        }
      },
      "LeadFormSubmission": {
        "type": "object",
        "title": "Lead form submission",
        "description": "The body for `book-demo`, `signup`, `events` and `contact`. All four reject a submission with no valid `email`.",
        "required": [
          "email"
        ],
        "additionalProperties": {
          "type": [
            "string",
            "number",
            "boolean",
            "null"
          ]
        },
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Required on book-demo, signup, events and contact."
          },
          "name": {
            "type": "string",
            "description": "Who is asking."
          },
          "company": {
            "type": "string",
            "description": "Where they work."
          },
          "message": {
            "type": "string",
            "description": "The body of a /contact enquiry."
          },
          "captcha_token": {
            "type": "string",
            "description": "reCAPTCHA Enterprise token. Browsers only; agents omit it."
          }
        }
      },
      "SurveySubmission": {
        "type": "object",
        "title": "Survey submission",
        "description": "The body for `survey`. No address is required: answering anonymously is supported, and so is answering as an agent, with no `captcha_token`. Answers to the survey's `multi` questions are arrays of the option strings, not a joined string. See /survey-agent.md and /survey-spec.json.",
        "additionalProperties": {
          "type": [
            "string",
            "number",
            "boolean",
            "null",
            "array"
          ],
          "items": {
            "type": "string"
          }
        },
        "properties": {
          "contact_email": {
            "type": "string",
            "format": "email",
            "description": "Optional. Supply it to be sent the report."
          },
          "captcha_token": {
            "type": "string",
            "description": "reCAPTCHA Enterprise token. Browsers only; agents omit it."
          }
        }
      },
      "FormResult": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "description": "True when the submission was accepted and forwarded."
          },
          "challenge": {
            "type": "boolean",
            "description": "True when a human needs to complete a checkbox in the browser. Nothing was stored."
          },
          "message": {
            "type": "string",
            "description": "Human-readable status."
          }
        }
      }
    }
  }
}
