{
 "openapi": "3.1.0",
 "info": {
  "title": "Liftpad API",
  "version": "1.0.0",
  "summary": "Website hosting, deploys, domains and forms on Liftpad.",
  "description": "The API behind the Liftpad dashboard, CLI and MCP server. Authenticate with an API token (Authorization: Bearer lp_...). Tokens are read or deploy: x-liftpad-scopes on each operation says the lowest one that works. Operations with x-liftpad-session-only work only from a signed-in dashboard session; x-liftpad-token-error is the error code an API token gets there (session_required, or forbidden for deleting or moving a site). Errors are JSON {error, message}. Times are milliseconds since 1970 (UTC). Rate limit: 1200 requests a minute per user. Human docs: https://liftpad.app/docs/",
  "x-liftpad-fr": {
   "summary": "Hébergement de sites, déploiements, domaines et formulaires sur Liftpad.",
   "description": "L'API derrière le tableau de bord, la CLI et le serveur MCP de Liftpad. Authentifiez-vous avec un jeton d'API (Authorization: Bearer lp_...). Les jetons sont read ou deploy : x-liftpad-scopes indique pour chaque opération le niveau minimal. Les opérations x-liftpad-session-only ne fonctionnent que depuis une session du tableau de bord; x-liftpad-token-error donne le code d'erreur reçu par un jeton d'API (session_required, ou forbidden pour supprimer ou déplacer un site). Les erreurs sont en JSON {error, message}. Les heures sont en millisecondes depuis 1970 (UTC). Limite : 1200 requêtes par minute par utilisateur. Documentation : https://liftpad.app/fr/docs/"
  },
  "contact": {
   "name": "Liftpad",
   "url": "https://liftpad.app/docs/"
  },
  "termsOfService": "https://liftpad.app/terms/"
 },
 "servers": [
  {
   "url": "https://api.liftpad.app/v1",
   "description": "Production"
  }
 ],
 "externalDocs": {
  "url": "https://liftpad.app/docs/",
  "description": "Liftpad developer docs"
 },
 "tags": [
  {
   "name": "sites",
   "description": "Create, read, move and delete sites.",
   "x-displayName": "Sites",
   "x-liftpad-fr": {
    "name": "Sites",
    "description": "Créer, lire, déplacer et supprimer des sites."
   }
  },
  {
   "name": "deploys",
   "description": "Upload only changed files, get a preview and launch checks, publish and roll back.",
   "x-displayName": "Deploys",
   "x-liftpad-fr": {
    "name": "Déploiements",
    "description": "Envoyer seulement les fichiers modifiés, obtenir un aperçu et des vérifications, publier et revenir en arrière."
   }
  },
  {
   "name": "domains",
   "description": "Search, buy and connect custom domains.",
   "x-displayName": "Domains",
   "x-liftpad-fr": {
    "name": "Domaines",
    "description": "Chercher, acheter et connecter des domaines."
   }
  },
  {
   "name": "forms",
   "description": "Form submissions found by Liftpad Forms (Netlify compatible).",
   "x-displayName": "Forms",
   "x-liftpad-fr": {
    "name": "Formulaires",
    "description": "Envois reçus par Liftpad Forms (compatible avec Netlify)."
   }
  },
  {
   "name": "settings",
   "description": "Code snippets, split tests, visitor password and notifications.",
   "x-displayName": "Site settings",
   "x-liftpad-fr": {
    "name": "Réglages du site",
    "description": "Extraits de code, tests A/B, mot de passe visiteur et notifications."
   }
  },
  {
   "name": "analytics",
   "description": "Cookie-free visitor statistics.",
   "x-displayName": "Analytics",
   "x-liftpad-fr": {
    "name": "Statistiques",
    "description": "Statistiques de visite sans témoins."
   }
  },
  {
   "name": "ai",
   "description": "Build and change sites in words (credits; dashboard session only).",
   "x-displayName": "AI website builder",
   "x-liftpad-fr": {
    "name": "Créateur de site IA",
    "description": "Créer et modifier des sites en mots (crédits; session du tableau de bord seulement)."
   }
  },
  {
   "name": "account",
   "description": "Who you are and your API tokens.",
   "x-displayName": "Account and tokens",
   "x-liftpad-fr": {
    "name": "Compte et jetons",
    "description": "Qui vous êtes et vos jetons d'API."
   }
  },
  {
   "name": "teams",
   "description": "Teams, members and invites.",
   "x-displayName": "Teams",
   "x-liftpad-fr": {
    "name": "Équipes",
    "description": "Équipes, membres et invitations."
   }
  },
  {
   "name": "billing",
   "description": "Plans in CAD, a team's billing and credits.",
   "x-displayName": "Plans, billing and credits",
   "x-liftpad-fr": {
    "name": "Forfaits, facturation et crédits",
    "description": "Forfaits en CAD, facturation et crédits d'une équipe."
   }
  },
  {
   "name": "audit",
   "description": "The audit log.",
   "x-displayName": "Activity",
   "x-liftpad-fr": {
    "name": "Activité",
    "description": "Le journal d'audit."
   }
  },
  {
   "name": "public",
   "description": "Routes anyone can call, without signing in.",
   "x-displayName": "Public",
   "x-liftpad-fr": {
    "name": "Public",
    "description": "Routes accessibles à tous, sans connexion."
   }
  },
  {
   "name": "mcp",
   "description": "The Model Context Protocol server for Claude and other agents.",
   "x-displayName": "MCP",
   "x-liftpad-fr": {
    "name": "MCP",
    "description": "Le serveur Model Context Protocol pour Claude et d'autres agents."
   }
  },
  {
   "name": "meta",
   "description": "The OpenAPI document itself.",
   "x-displayName": "This reference",
   "x-liftpad-fr": {
    "name": "Cette référence",
    "description": "Le document OpenAPI lui-même."
   }
  }
 ],
 "security": [
  {
   "bearer": []
  },
  {
   "session": []
  }
 ],
 "paths": {
  "/sites": {
   "get": {
    "operationId": "listSites",
    "tags": [
     "sites"
    ],
    "summary": "List sites",
    "description": "Every site you can see (a token limited to one team sees that team's sites only).",
    "x-liftpad-fr": {
     "summary": "Lister les sites",
     "description": "Tous les sites que vous voyez (un jeton limité à une équipe ne voit que les siens)."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamQuery"
     }
    ],
    "responses": {
     "200": {
      "description": "The sites, by name",
      "x-liftpad-fr": "Les sites, par nom",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Site"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "operationId": "createSite",
    "tags": [
     "sites"
    ],
    "summary": "Create a site",
    "description": "Creates an empty site. It is served at https://<name>.liftpad.ca once a deploy is published. Give team when you belong to several teams.",
    "x-liftpad-fr": {
     "summary": "Créer un site",
     "description": "Crée un site vide, servi à https://<nom>.liftpad.ca dès qu'un déploiement est publié. Indiquez team si vous faites partie de plusieurs équipes."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "3 to 40 characters: a-z, 0-9 and single hyphens",
          "x-liftpad-fr": "3 à 40 caractères : a-z, 0-9 et traits d'union simples"
         },
         "team": {
          "type": "string",
          "description": "Team slug",
          "x-liftpad-fr": "Slug de l'équipe"
         }
        },
        "required": [
         "name"
        ]
       },
       "example": {
        "name": "my-site",
        "team": "my-agency"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Created",
      "x-liftpad-fr": "Créé",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string"
          },
          "name": {
           "type": "string"
          },
          "team": {
           "type": "string"
          },
          "url": {
           "type": "string"
          }
         },
         "required": [
          "id",
          "name",
          "team",
          "url"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}": {
   "get": {
    "operationId": "getSite",
    "tags": [
     "sites"
    ],
    "summary": "Get a site",
    "x-liftpad-fr": {
     "summary": "Obtenir un site"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "The site",
      "x-liftpad-fr": "Le site",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SiteDetail"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "operationId": "deleteSite",
    "tags": [
     "sites"
    ],
    "summary": "Delete a site",
    "description": "Takes the site offline for good, releases its domains and frees its name. Send the site's name as confirm.",
    "x-liftpad-fr": {
     "summary": "Supprimer un site",
     "description": "Met le site hors ligne pour de bon, libère ses domaines et son nom. Envoyez le nom du site dans confirm."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "forbidden",
    "x-liftpad-role": "owner",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "confirm": {
          "type": "string",
          "description": "The site's name",
          "x-liftpad-fr": "Le nom du site"
         }
        },
        "required": [
         "confirm"
        ]
       },
       "example": {
        "confirm": "my-site"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Deleted",
      "x-liftpad-fr": "Supprimé",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "502": {
      "$ref": "#/components/responses/E502"
     }
    }
   }
  },
  "/sites/{name}/transfer": {
   "post": {
    "operationId": "transferSite",
    "tags": [
     "sites"
    ],
    "summary": "Move a site to another team",
    "description": "For an owner of both teams. Files, deploys and domains move with the site, within the receiving team's plan.",
    "x-liftpad-fr": {
     "summary": "Déplacer un site vers une autre équipe",
     "description": "Pour un propriétaire des deux équipes. Fichiers, déploiements et domaines suivent le site, dans les limites du forfait de l'équipe qui le reçoit."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "forbidden",
    "x-liftpad-role": "owner",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "team": {
          "type": "string",
          "description": "Slug of the receiving team",
          "x-liftpad-fr": "Slug de l'équipe qui reçoit"
         }
        },
        "required": [
         "team"
        ]
       },
       "example": {
        "team": "client-team"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Moved",
      "x-liftpad-fr": "Déplacé",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "site": {
           "type": "string"
          },
          "team": {
           "type": "string"
          }
         },
         "required": [
          "ok",
          "site",
          "team"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "413": {
      "$ref": "#/components/responses/E413"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/overview": {
   "get": {
    "operationId": "getOverview",
    "tags": [
     "sites"
    ],
    "summary": "Sites with health and last publish",
    "x-liftpad-fr": {
     "summary": "Sites avec état de santé et dernière publication"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamQuery"
     }
    ],
    "responses": {
     "200": {
      "description": "Overview",
      "x-liftpad-fr": "Vue d'ensemble",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Overview"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/manifest": {
   "get": {
    "operationId": "getManifest",
    "tags": [
     "sites"
    ],
    "summary": "Get a deploy's manifest",
    "description": "Every file path with its SHA-256, size and type, plus the deploy's rules. Used by exports and by deploy_changes.",
    "x-liftpad-fr": {
     "summary": "Obtenir le manifeste d'un déploiement",
     "description": "Chaque chemin avec son SHA-256, sa taille et son type, et les règles du déploiement. Sert aux exportations et à deploy_changes."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "$ref": "#/components/parameters/DeployQuery"
     }
    ],
    "responses": {
     "200": {
      "description": "The manifest",
      "x-liftpad-fr": "Le manifeste",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Manifest"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/files/{hash}": {
   "get": {
    "operationId": "getSiteFile",
    "tags": [
     "sites"
    ],
    "summary": "Download one file of a deploy",
    "description": "Same right as the manifest: the files include the site's rules (Basic-Auth passwords) and protected pages. Always sent as a download.",
    "x-liftpad-fr": {
     "summary": "Télécharger un fichier d'un déploiement",
     "description": "Même droit que le manifeste : les fichiers comprennent les règles du site (mots de passe Basic-Auth) et les pages protégées. Toujours envoyé en téléchargement."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "$ref": "#/components/parameters/Hash"
     },
     {
      "$ref": "#/components/parameters/DeployQuery"
     }
    ],
    "responses": {
     "200": {
      "description": "The file's bytes",
      "x-liftpad-fr": "Le contenu du fichier",
      "content": {
       "application/octet-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/deploys": {
   "post": {
    "operationId": "createDeploy",
    "tags": [
     "deploys"
    ],
    "summary": "Start a deploy",
    "description": "Send every file path with the SHA-256 of its bytes. The answer lists the hashes Liftpad does not have yet: upload only those, then finalize. Files your team already uploaded are reused.",
    "x-liftpad-fr": {
     "summary": "Commencer un déploiement",
     "description": "Envoyez chaque chemin avec le SHA-256 de son contenu. La réponse donne les empreintes que Liftpad n'a pas encore : envoyez seulement celles-là, puis finalisez. Les fichiers déjà envoyés par votre équipe sont réutilisés."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "files": {
          "type": "object",
          "additionalProperties": {
           "type": "string",
           "pattern": "^[a-f0-9]{64}$",
           "description": "SHA-256 of the file's bytes, 64 lowercase hex characters",
           "x-liftpad-fr": "SHA-256 du contenu du fichier, 64 caractères hexadécimaux minuscules"
          },
          "description": "Path (starting with /) to SHA-256, at most 20 000 files",
          "x-liftpad-fr": "Chemin (commençant par /) vers SHA-256, au plus 20 000 fichiers"
         },
         "title": {
          "type": "string",
          "description": "Deploy message",
          "x-liftpad-fr": "Message du déploiement"
         },
         "config": {
          "type": "string",
          "description": "Text of a netlify.toml (up to 1 MB)",
          "x-liftpad-fr": "Texte d'un netlify.toml (jusqu'à 1 Mo)"
         },
         "rules": {
          "type": "object",
          "properties": {
           "redirects": {
            "type": "array",
            "items": {
             "type": "object"
            }
           },
           "headers": {
            "type": "array",
            "items": {
             "type": "object"
            }
           }
          },
          "required": [
           "redirects",
           "headers"
          ],
          "description": "Rules from a site export (restore)",
          "x-liftpad-fr": "Règles d'une exportation de site (restauration)"
         }
        },
        "required": [
         "files"
        ]
       },
       "example": {
        "files": {
         "/index.html": "3a1f0c8e5b0d2d8f9c4e1a7b6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c",
         "/style.css": "9f8e7d6c5b4a39281706f5e4d3c2b1a0f9e8d7c6b5a493827160f5e4d3c2b1a0"
        },
        "title": "First deploy"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Deploy started",
      "x-liftpad-fr": "Déploiement commencé",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string"
          },
          "required": {
           "type": "array",
           "items": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "SHA-256 of the file's bytes, 64 lowercase hex characters",
            "x-liftpad-fr": "SHA-256 du contenu du fichier, 64 caractères hexadécimaux minuscules"
           },
           "description": "Hashes to upload",
           "x-liftpad-fr": "Empreintes à envoyer"
          },
          "previewUrl": {
           "type": "string"
          }
         },
         "required": [
          "id",
          "required",
          "previewUrl"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "413": {
      "$ref": "#/components/responses/E413"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "get": {
    "operationId": "listDeploys",
    "tags": [
     "deploys"
    ],
    "summary": "List a site's deploys",
    "description": "The newest 100.",
    "x-liftpad-fr": {
     "summary": "Lister les déploiements d'un site",
     "description": "Les 100 plus récents."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Deploys, newest first",
      "x-liftpad-fr": "Déploiements, du plus récent au plus ancien",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/DeployListItem"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/deploys/{id}/blobs/{hash}": {
   "put": {
    "operationId": "uploadDeployFile",
    "tags": [
     "deploys"
    ],
    "summary": "Upload one file",
    "description": "The raw bytes of one file the deploy asked for, with Content-Length. Liftpad checks the bytes against the hash. Up to 100 MB per file.",
    "x-liftpad-fr": {
     "summary": "Envoyer un fichier",
     "description": "Le contenu brut d'un fichier demandé par le déploiement, avec Content-Length. Liftpad vérifie le contenu par rapport à l'empreinte. Jusqu'à 100 Mo par fichier."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/DeployId"
     },
     {
      "$ref": "#/components/parameters/Hash"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/octet-stream": {
       "schema": {
        "type": "string",
        "format": "binary"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Stored",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "hash": {
           "type": "string"
          },
          "size": {
           "type": "integer"
          }
         },
         "required": [
          "ok",
          "hash",
          "size"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "411": {
      "$ref": "#/components/responses/E411"
     },
     "413": {
      "$ref": "#/components/responses/E413"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/deploys/{id}/finalize": {
   "post": {
    "operationId": "finalizeDeploy",
    "tags": [
     "deploys"
    ],
    "summary": "Finish a deploy",
    "description": "Reads the rules and forms, runs the launch checks and makes the preview address work. If files are missing the answer is 409 missing_blobs with the hashes to upload; upload them and call again. Calling it on a ready deploy answers ready again.",
    "x-liftpad-fr": {
     "summary": "Terminer un déploiement",
     "description": "Lit les règles et les formulaires, lance les vérifications de lancement et active l'adresse d'aperçu. S'il manque des fichiers, la réponse est 409 missing_blobs avec les empreintes à envoyer; envoyez-les et rappelez. Sur un déploiement déjà prêt, la réponse est de nouveau ready."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/DeployId"
     }
    ],
    "responses": {
     "200": {
      "description": "Ready",
      "x-liftpad-fr": "Prêt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string"
          },
          "state": {
           "type": "string",
           "const": "ready"
          },
          "previewUrl": {
           "type": "string"
          },
          "summary": {
           "$ref": "#/components/schemas/DeploySummary"
          },
          "held": {
           "type": "boolean",
           "description": "Held for a Liftpad safety review",
           "x-liftpad-fr": "Retenu pour une vérification de sécurité"
          },
          "message": {
           "type": "string"
          }
         },
         "required": [
          "id",
          "state"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "413": {
      "$ref": "#/components/responses/E413"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/deploys/{id}": {
   "get": {
    "operationId": "getDeploy",
    "tags": [
     "deploys"
    ],
    "summary": "Get a deploy",
    "x-liftpad-fr": {
     "summary": "Obtenir un déploiement"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/DeployId"
     }
    ],
    "responses": {
     "200": {
      "description": "The deploy",
      "x-liftpad-fr": "Le déploiement",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Deploy"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/deploys/{id}/checks": {
   "get": {
    "operationId": "getDeployChecks",
    "tags": [
     "deploys"
    ],
    "summary": "Launch checks of a deploy",
    "description": "Broken links, missing files, titles, descriptions, alt text, insecure content, heavy images, sitemap, robots.txt and more, read from up to 400 pages.",
    "x-liftpad-fr": {
     "summary": "Vérifications de lancement d'un déploiement",
     "description": "Liens brisés, fichiers manquants, titres, descriptions, texte de remplacement, contenu non sécurisé, images lourdes, plan du site, robots.txt et plus, lus dans jusqu'à 400 pages."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/DeployId"
     }
    ],
    "responses": {
     "200": {
      "description": "The report",
      "x-liftpad-fr": "Le rapport",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CheckReport"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/deploys/{id}/suggest": {
   "post": {
    "operationId": "suggestPageMeta",
    "tags": [
     "deploys"
    ],
    "summary": "AI title and description for a page",
    "description": "Written from the page's own text. Uses the plan's monthly AI suggestions; the same page content is answered from cache for free.",
    "x-liftpad-fr": {
     "summary": "Titre et description d'une page par IA",
     "description": "Rédigés à partir du texte de la page. Utilise les suggestions IA mensuelles du forfait; un contenu déjà traité est servi gratuitement."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/DeployId"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "page": {
          "type": "string",
          "description": "Path of an HTML page in the deploy",
          "x-liftpad-fr": "Chemin d'une page HTML du déploiement"
         }
        },
        "required": [
         "page"
        ]
       },
       "example": {
        "page": "/about.html"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Suggestion",
      "x-liftpad-fr": "Suggestion",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "title": {
           "type": "string"
          },
          "description": {
           "type": "string"
          },
          "cached": {
           "type": "boolean"
          },
          "left": {
           "type": "integer",
           "description": "Suggestions left this month",
           "x-liftpad-fr": "Suggestions restantes ce mois-ci"
          }
         },
         "required": [
          "title",
          "description",
          "cached"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/deploys/{id}/alt": {
   "post": {
    "operationId": "suggestImageAlt",
    "tags": [
     "deploys"
    ],
    "summary": "AI alt text for an image",
    "description": "A vision model describes one image of the deploy in one sentence, in the page's language.",
    "x-liftpad-fr": {
     "summary": "Texte de remplacement d'une image par IA",
     "description": "Un modèle de vision décrit une image du déploiement en une phrase, dans la langue de la page."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/DeployId"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "page": {
          "type": "string",
          "description": "The page that shows the image",
          "x-liftpad-fr": "La page qui montre l'image"
         },
         "src": {
          "type": "string",
          "description": "The image address as written in the page",
          "x-liftpad-fr": "L'adresse de l'image telle qu'écrite dans la page"
         }
        },
        "required": [
         "page",
         "src"
        ]
       },
       "example": {
        "page": "/index.html",
        "src": "img/team.jpg"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Alt text",
      "x-liftpad-fr": "Texte de remplacement",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "alt": {
           "type": "string"
          },
          "lang": {
           "type": "string"
          },
          "src": {
           "type": "string"
          },
          "cached": {
           "type": "boolean"
          }
         },
         "required": [
          "alt",
          "cached"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/publish": {
   "post": {
    "operationId": "publishDeploy",
    "tags": [
     "deploys"
    ],
    "summary": "Publish a deploy (or roll back)",
    "description": "Makes a ready deploy live everywhere within about 5 seconds. Publishing an older deploy is a rollback. Ends a running split test.",
    "x-liftpad-fr": {
     "summary": "Publier un déploiement (ou revenir en arrière)",
     "description": "Met un déploiement prêt en ligne partout en environ 5 secondes. Publier un ancien déploiement est un retour arrière. Met fin à un test A/B en cours."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "deployId": {
          "type": "string"
         }
        },
        "required": [
         "deployId"
        ]
       },
       "example": {
        "deployId": "k2j4h6g8f0d2"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Live",
      "x-liftpad-fr": "En ligne",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "site": {
           "type": "string"
          },
          "deployId": {
           "type": "string"
          },
          "generation": {
           "type": "integer"
          },
          "url": {
           "type": "string",
           "description": "The live address (primary domain when there is one)",
           "x-liftpad-fr": "L'adresse en ligne (domaine principal s'il y en a un)"
          }
         },
         "required": [
          "site",
          "deployId",
          "generation",
          "url"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "503": {
      "$ref": "#/components/responses/E503"
     }
    }
   }
  },
  "/sites/{name}/unpublish": {
   "post": {
    "operationId": "unpublishSite",
    "tags": [
     "deploys"
    ],
    "summary": "Take a site offline",
    "description": "Nothing is deleted: publish a deploy again to bring it back.",
    "x-liftpad-fr": {
     "summary": "Mettre un site hors ligne",
     "description": "Rien n'est supprimé : publiez un déploiement pour le remettre en ligne."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Offline",
      "x-liftpad-fr": "Hors ligne",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/domains": {
   "post": {
    "operationId": "addDomain",
    "tags": [
     "domains"
    ],
    "summary": "Connect a domain you own",
    "description": "Answers with the DNS records to add. HTTPS starts once DNS points at Liftpad. With primary, the domain becomes the main address as soon as it is ready.",
    "x-liftpad-fr": {
     "summary": "Connecter un domaine que vous possédez",
     "description": "Répond avec les enregistrements DNS à ajouter. HTTPS démarre dès que le DNS pointe vers Liftpad. Avec primary, le domaine devient l'adresse principale dès qu'il est prêt."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "hostname": {
          "type": "string",
          "example": "www.example.com"
         },
         "primary": {
          "type": "boolean",
          "description": "Make it the main address once ready",
          "x-liftpad-fr": "En faire l'adresse principale une fois prêt"
         }
        },
        "required": [
         "hostname"
        ]
       },
       "example": {
        "hostname": "www.example.com",
        "primary": true
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Added",
      "x-liftpad-fr": "Ajouté",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "hostname": {
           "type": "string"
          },
          "site": {
           "type": "string"
          },
          "primary": {
           "type": "boolean"
          },
          "mainWhenReady": {
           "type": "boolean"
          },
          "status": {
           "type": "string"
          },
          "sslStatus": {
           "type": "string"
          },
          "records": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         },
         "required": [
          "hostname",
          "status",
          "records"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "502": {
      "$ref": "#/components/responses/E502"
     }
    }
   },
   "get": {
    "operationId": "listDomains",
    "tags": [
     "domains"
    ],
    "summary": "List a site's domains",
    "description": "With fresh DNS and certificate status (checked at most once a minute).",
    "x-liftpad-fr": {
     "summary": "Lister les domaines d'un site",
     "description": "Avec l'état DNS et du certificat à jour (vérifié au plus une fois par minute)."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Domains",
      "x-liftpad-fr": "Domaines",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Domain"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/domains/{hostname}": {
   "delete": {
    "operationId": "removeDomain",
    "tags": [
     "domains"
    ],
    "summary": "Remove a domain",
    "description": "A domain bought on Liftpad stays connected while it is registered.",
    "x-liftpad-fr": {
     "summary": "Retirer un domaine",
     "description": "Un domaine acheté sur Liftpad reste connecté tant qu'il est enregistré."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "hostname",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The domain",
      "x-liftpad-fr": "Le domaine"
     }
    ],
    "responses": {
     "200": {
      "description": "Removed",
      "x-liftpad-fr": "Retiré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "502": {
      "$ref": "#/components/responses/E502"
     }
    }
   }
  },
  "/sites/{name}/primary": {
   "post": {
    "operationId": "setPrimaryDomain",
    "tags": [
     "domains"
    ],
    "summary": "Choose the main address",
    "description": "Visitors on other addresses are sent to the main one. null goes back to the liftpad.ca address. A domain that is not ready yet becomes the main one automatically when it is (409 domain_not_ready).",
    "x-liftpad-fr": {
     "summary": "Choisir l'adresse principale",
     "description": "Les visiteurs des autres adresses sont envoyés vers la principale. null revient à l'adresse liftpad.ca. Un domaine pas encore prêt deviendra principal automatiquement (409 domain_not_ready)."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "hostname": {
          "type": [
           "string",
           "null"
          ]
         }
        },
        "required": [
         "hostname"
        ]
       },
       "example": {
        "hostname": "www.example.com"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Set",
      "x-liftpad-fr": "Choisie",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "primary": {
           "type": [
            "string",
            "null"
           ]
          }
         },
         "required": [
          "ok",
          "primary"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains/search": {
   "get": {
    "operationId": "searchDomains",
    "tags": [
     "domains"
    ],
    "summary": "Search domain names",
    "description": "Is a name free, and its price in CAD. No sign-in needed. Answers for the same names are cached for ten minutes.",
    "x-liftpad-fr": {
     "summary": "Chercher des noms de domaine",
     "description": "Un nom est-il libre, et son prix en CAD. Aucune connexion requise. Les mêmes noms sont gardés en cache dix minutes."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-role": "none",
    "security": [],
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "A name or words, up to 100 characters",
      "x-liftpad-fr": "Un nom ou des mots, jusqu'à 100 caractères"
     }
    ],
    "responses": {
     "200": {
      "description": "Results",
      "x-liftpad-fr": "Résultats",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DomainSearch"
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "502": {
      "$ref": "#/components/responses/E502"
     },
     "503": {
      "$ref": "#/components/responses/E503"
     }
    }
   }
  },
  "/sites/{name}/domain-orders": {
   "get": {
    "operationId": "listDomainOrders",
    "tags": [
     "domains"
    ],
    "summary": "Domain orders of a site",
    "x-liftpad-fr": {
     "summary": "Commandes de domaines d'un site"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Orders",
      "x-liftpad-fr": "Commandes",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "orders": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/DomainOrder"
           }
          },
          "includedLeft": {
           "type": "integer",
           "description": "Included domains left this year",
           "x-liftpad-fr": "Domaines inclus restants cette année"
          },
          "includedPlan": {
           "type": "boolean"
          },
          "ready": {
           "type": "boolean",
           "description": "Domain sales are open",
           "x-liftpad-fr": "La vente de domaines est ouverte"
          },
          "payments": {
           "type": "boolean",
           "description": "Online payment is open",
           "x-liftpad-fr": "Le paiement en ligne est ouvert"
          }
         },
         "required": [
          "orders"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/domains/buy": {
   "post": {
    "operationId": "buyDomain",
    "tags": [
     "domains"
    ],
    "summary": "Buy a domain for a site",
    "description": "Owners and admins, from the dashboard. Uses the plan's included domain when it covers the name; otherwise answers with a Stripe checkout address, or sends the request to Liftpad when online payment is not open.",
    "x-liftpad-fr": {
     "summary": "Acheter un domaine pour un site",
     "description": "Propriétaires et administrateurs, depuis le tableau de bord. Utilise le domaine inclus au forfait s'il couvre le nom; sinon répond avec une adresse de paiement Stripe, ou transmet la demande à Liftpad si le paiement en ligne n'est pas ouvert."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "admin",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "domain": {
          "type": "string",
          "example": "yourbusiness.ca"
         }
        },
        "required": [
         "domain"
        ]
       },
       "example": {
        "domain": "yourbusiness.ca"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Ordered",
      "x-liftpad-fr": "Commandé",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "order": {
           "$ref": "#/components/schemas/DomainOrder"
          },
          "checkoutUrl": {
           "type": "string",
           "description": "Stripe payment page, when payment is needed",
           "x-liftpad-fr": "Page de paiement Stripe, si un paiement est requis"
          }
         },
         "required": [
          "order"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "502": {
      "$ref": "#/components/responses/E502"
     },
     "503": {
      "$ref": "#/components/responses/E503"
     }
    }
   }
  },
  "/sites/{name}/snippets": {
   "get": {
    "operationId": "getSnippets",
    "tags": [
     "settings"
    ],
    "summary": "Get code snippets",
    "x-liftpad-fr": {
     "summary": "Obtenir les extraits de code"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Snippets",
      "x-liftpad-fr": "Extraits",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Snippet"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "put": {
    "operationId": "setSnippets",
    "tags": [
     "settings"
    ],
    "summary": "Replace code snippets",
    "description": "The whole list: up to 10 snippets, 20 000 characters each, 50 000 in all, added to every HTML page without a deploy. Paid plans only.",
    "x-liftpad-fr": {
     "summary": "Remplacer les extraits de code",
     "description": "La liste complète : jusqu'à 10 extraits, 20 000 caractères chacun, 50 000 en tout, ajoutés à chaque page HTML sans déploiement. Forfaits payants seulement."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "snippets": {
          "type": "array",
          "items": {
           "$ref": "#/components/schemas/Snippet"
          }
         }
        },
        "required": [
         "snippets"
        ]
       },
       "example": {
        "snippets": [
         {
          "name": "Analytics",
          "where": "head",
          "html": "<script defer src=\"https://example.com/a.js\"></script>"
         }
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The saved list",
      "x-liftpad-fr": "La liste enregistrée",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Snippet"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/split": {
   "get": {
    "operationId": "getSplitTest",
    "tags": [
     "settings"
    ],
    "summary": "Get the split test",
    "x-liftpad-fr": {
     "summary": "Obtenir le test A/B"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "The test, or null",
      "x-liftpad-fr": "Le test, ou null",
      "content": {
       "application/json": {
        "schema": {
         "oneOf": [
          {
           "$ref": "#/components/schemas/SplitTest"
          },
          {
           "type": "null"
          }
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "put": {
    "operationId": "setSplitTest",
    "tags": [
     "settings"
    ],
    "summary": "Start, change or stop a split test",
    "description": "A share of the live site's visitors (1 to 99 %) sees another ready deploy. Send deployId null to stop.",
    "x-liftpad-fr": {
     "summary": "Lancer, modifier ou arrêter un test A/B",
     "description": "Une part des visiteurs du site en ligne (1 à 99 %) voit un autre déploiement prêt. Envoyez deployId null pour arrêter."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "deployId": {
          "type": [
           "string",
           "null"
          ]
         },
         "percent": {
          "type": "integer",
          "minimum": 1,
          "maximum": 99
         }
        },
        "required": [
         "deployId"
        ]
       },
       "example": {
        "deployId": "k2j4h6g8f0d2",
        "percent": 20
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The test, or null",
      "x-liftpad-fr": "Le test, ou null",
      "content": {
       "application/json": {
        "schema": {
         "oneOf": [
          {
           "$ref": "#/components/schemas/SplitTest"
          },
          {
           "type": "null"
          }
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/access": {
   "get": {
    "operationId": "getVisitorAccess",
    "tags": [
     "settings"
    ],
    "summary": "Visitor password status",
    "x-liftpad-fr": {
     "summary": "État du mot de passe visiteur"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Status",
      "x-liftpad-fr": "État",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "enabled": {
           "type": "boolean"
          },
          "scope": {
           "type": [
            "string",
            "null"
           ],
           "enum": [
            "all",
            "previews",
            null
           ]
          },
          "updatedAt": {
           "type": [
            "integer",
            "null"
           ]
          }
         },
         "required": [
          "enabled",
          "scope"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "put": {
    "operationId": "setVisitorAccess",
    "tags": [
     "settings"
    ],
    "summary": "Set or remove the visitor password",
    "description": "A password page in front of the whole site or only its previews. password null removes it. Changing it signs every visitor out. Not possible with an API token.",
    "x-liftpad-fr": {
     "summary": "Définir ou retirer le mot de passe visiteur",
     "description": "Une page de mot de passe devant tout le site ou seulement ses aperçus. password null le retire. Le changer déconnecte tous les visiteurs. Impossible avec un jeton d'API."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "password": {
          "type": [
           "string",
           "null"
          ],
          "description": "8 to 200 characters, or null",
          "x-liftpad-fr": "8 à 200 caractères, ou null"
         },
         "scope": {
          "type": "string",
          "enum": [
           "all",
           "previews"
          ]
         }
        },
        "required": [
         "password"
        ]
       },
       "example": {
        "password": "a long shared password",
        "scope": "previews"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Saved",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "enabled": {
           "type": "boolean"
          },
          "scope": {
           "type": [
            "string",
            "null"
           ]
          }
         },
         "required": [
          "ok",
          "enabled"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/hooks": {
   "get": {
    "operationId": "listHooks",
    "tags": [
     "settings"
    ],
    "summary": "List notifications",
    "description": "Webhooks and Slack messages of a site. Dashboard session only.",
    "x-liftpad-fr": {
     "summary": "Lister les notifications",
     "description": "Webhooks et messages Slack d'un site. Session du tableau de bord seulement."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Notifications",
      "x-liftpad-fr": "Notifications",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Hook"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "operationId": "createHook",
    "tags": [
     "settings"
    ],
    "summary": "Add a notification",
    "description": "A signed webhook or a Slack incoming webhook for some of: deploy.ready, deploy.published, form.submission. Public https addresses only, never Liftpad or a site it hosts. Up to 10 per site. A webhook's signing secret is in this answer only.",
    "x-liftpad-fr": {
     "summary": "Ajouter une notification",
     "description": "Un webhook signé ou un webhook entrant Slack pour certains de : deploy.ready, deploy.published, form.submission. Adresses https publiques seulement, jamais Liftpad ni un site qu'il héberge. Jusqu'à 10 par site. Le secret de signature d'un webhook n'apparaît que dans cette réponse."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "kind": {
          "type": "string",
          "enum": [
           "webhook",
           "slack"
          ]
         },
         "url": {
          "type": "string",
          "format": "uri"
         },
         "events": {
          "type": "array",
          "items": {
           "type": "string",
           "enum": [
            "deploy.ready",
            "deploy.published",
            "form.submission"
           ]
          }
         }
        },
        "required": [
         "kind",
         "url",
         "events"
        ]
       },
       "example": {
        "kind": "webhook",
        "url": "https://example.com/liftpad",
        "events": [
         "deploy.published",
         "form.submission"
        ]
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Added",
      "x-liftpad-fr": "Ajoutée",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string",
           "example": "hook_a1b2c3d4e5f6"
          },
          "kind": {
           "type": "string",
           "enum": [
            "webhook",
            "slack"
           ]
          },
          "url": {
           "type": "string",
           "description": "Where events are sent (Slack addresses are shown shortened)",
           "x-liftpad-fr": "Où les événements sont envoyés (adresses Slack raccourcies)"
          },
          "events": {
           "type": "array",
           "items": {
            "type": "string",
            "enum": [
             "deploy.ready",
             "deploy.published",
             "form.submission"
            ]
           }
          },
          "createdAt": {
           "type": "integer"
          },
          "lastStatus": {
           "type": [
            "integer",
            "null"
           ],
           "description": "HTTP status of the last delivery (0 when it could not connect)",
           "x-liftpad-fr": "Statut HTTP du dernier envoi (0 si la connexion a échoué)"
          },
          "lastAt": {
           "type": [
            "integer",
            "null"
           ]
          },
          "paused": {
           "type": "boolean",
           "description": "True after 50 failed deliveries in a row",
           "x-liftpad-fr": "Vrai après 50 envois ratés de suite"
          },
          "secret": {
           "type": "string",
           "description": "Signing secret (lpwh_...), shown once",
           "x-liftpad-fr": "Secret de signature (lpwh_...), montré une fois"
          }
         },
         "required": [
          "id",
          "kind",
          "url",
          "events"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/hooks/{id}/test": {
   "post": {
    "operationId": "testHook",
    "tags": [
     "settings"
    ],
    "summary": "Send a test notification",
    "x-liftpad-fr": {
     "summary": "Envoyer une notification d'essai"
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Notification id",
      "x-liftpad-fr": "Identifiant de la notification"
     }
    ],
    "responses": {
     "200": {
      "description": "How the delivery went",
      "x-liftpad-fr": "Résultat de l'envoi",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "integer",
           "description": "HTTP status of the receiver (0 when it could not connect)",
           "x-liftpad-fr": "Statut HTTP du destinataire (0 si la connexion a échoué)"
          },
          "ok": {
           "type": "boolean"
          }
         },
         "required": [
          "status",
          "ok"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/hooks/{id}": {
   "delete": {
    "operationId": "deleteHook",
    "tags": [
     "settings"
    ],
    "summary": "Remove a notification",
    "x-liftpad-fr": {
     "summary": "Retirer une notification"
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Notification id",
      "x-liftpad-fr": "Identifiant de la notification"
     }
    ],
    "responses": {
     "200": {
      "description": "Removed",
      "x-liftpad-fr": "Retirée",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/forms": {
   "get": {
    "operationId": "listForms",
    "tags": [
     "forms"
    ],
    "summary": "List forms",
    "description": "Forms of the live deploy, with how many submissions each has received.",
    "x-liftpad-fr": {
     "summary": "Lister les formulaires",
     "description": "Formulaires du déploiement en ligne, avec le nombre d'envois reçus."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Forms",
      "x-liftpad-fr": "Formulaires",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "allowance": {
           "type": [
            "integer",
            "null"
           ],
           "description": "Submissions per month on the plan",
           "x-liftpad-fr": "Envois par mois au forfait"
          },
          "forms": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Form"
           }
          }
         },
         "required": [
          "forms"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/submissions": {
   "get": {
    "operationId": "listSubmissions",
    "tags": [
     "forms"
    ],
    "summary": "List form submissions",
    "description": "Newest first. Pass next as before to get the following page.",
    "x-liftpad-fr": {
     "summary": "Lister les envois de formulaire",
     "description": "Du plus récent au plus ancien. Passez next comme before pour la page suivante."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "form",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Only this form",
      "x-liftpad-fr": "Seulement ce formulaire"
     },
     {
      "name": "spam",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "0",
        "1"
       ]
      },
      "description": "1 for the spam folder",
      "x-liftpad-fr": "1 pour les indésirables"
     },
     {
      "name": "before",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      },
      "description": "Only submissions older than this time (ms)",
      "x-liftpad-fr": "Seulement les envois plus anciens que ce moment (ms)"
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 200
      },
      "description": "1 to 200, default 50",
      "x-liftpad-fr": "1 à 200, 50 par défaut"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of submissions",
      "x-liftpad-fr": "Une page d'envois",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "submissions": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Submission"
           }
          },
          "next": {
           "type": [
            "integer",
            "null"
           ],
           "description": "Value for before, or null at the end",
           "x-liftpad-fr": "Valeur pour before, ou null à la fin"
          }
         },
         "required": [
          "submissions",
          "next"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/forms/{form}/submissions.csv": {
   "get": {
    "operationId": "exportSubmissionsCsv",
    "tags": [
     "forms"
    ],
    "summary": "Download submissions as CSV",
    "description": "Every submission of one form, safe to open in a spreadsheet (values that would run as formulas are quoted). Up to 50 000 rows.",
    "x-liftpad-fr": {
     "summary": "Télécharger les envois en CSV",
     "description": "Tous les envois d'un formulaire, sûrs à ouvrir dans un tableur (les valeurs qui seraient lues comme formules sont neutralisées). Jusqu'à 50 000 lignes."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "form",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Form name",
      "x-liftpad-fr": "Nom du formulaire"
     }
    ],
    "responses": {
     "200": {
      "description": "CSV file",
      "x-liftpad-fr": "Fichier CSV",
      "content": {
       "text/csv": {
        "schema": {
         "type": "string"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/submissions/{id}/files/{i}": {
   "get": {
    "operationId": "getSubmissionFile",
    "tags": [
     "forms"
    ],
    "summary": "Download a file sent with a submission",
    "description": "Always sent as a download, never shown in the browser (it came from a visitor).",
    "x-liftpad-fr": {
     "summary": "Télécharger un fichier joint à un envoi",
     "description": "Toujours envoyé en téléchargement, jamais affiché (il vient d'un visiteur)."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Submission id",
      "x-liftpad-fr": "Identifiant de l'envoi"
     },
     {
      "name": "i",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "File index from the submission's files",
      "x-liftpad-fr": "Index du fichier dans files"
     }
    ],
    "responses": {
     "200": {
      "description": "The file",
      "x-liftpad-fr": "Le fichier",
      "content": {
       "application/octet-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/submissions/{id}": {
   "patch": {
    "operationId": "markSubmission",
    "tags": [
     "forms"
    ],
    "summary": "Mark as spam or not spam",
    "x-liftpad-fr": {
     "summary": "Marquer comme indésirable ou non"
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Submission id",
      "x-liftpad-fr": "Identifiant de l'envoi"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "spam": {
          "type": "boolean"
         }
        },
        "required": [
         "spam"
        ]
       },
       "example": {
        "spam": true
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Saved",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "operationId": "deleteSubmission",
    "tags": [
     "forms"
    ],
    "summary": "Delete a submission",
    "description": "Its files are deleted too.",
    "x-liftpad-fr": {
     "summary": "Supprimer un envoi",
     "description": "Ses fichiers sont aussi supprimés."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Submission id",
      "x-liftpad-fr": "Identifiant de l'envoi"
     }
    ],
    "responses": {
     "200": {
      "description": "Deleted",
      "x-liftpad-fr": "Supprimé",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/submissions/import": {
   "post": {
    "operationId": "importSubmissions",
    "tags": [
     "forms"
    ],
    "summary": "Import submissions from another host",
    "description": "Up to 500 per call. Dates are kept, nobody is emailed and files are not copied. Sending the same id twice imports it once.",
    "x-liftpad-fr": {
     "summary": "Importer des envois d'un autre hébergeur",
     "description": "Jusqu'à 500 par appel. Les dates sont gardées, personne n'est avisé par courriel et les fichiers ne sont pas copiés. Le même id envoyé deux fois n'est importé qu'une fois."
    },
    "x-liftpad-scopes": [
     "deploy"
    ],
    "x-liftpad-role": "developer",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "submissions": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "id": {
             "type": "string",
             "description": "Your id, to skip repeats",
             "x-liftpad-fr": "Votre identifiant, pour éviter les doublons"
            },
            "form": {
             "type": "string"
            },
            "data": {
             "type": "object",
             "additionalProperties": {
              "type": "string"
             }
            },
            "createdAt": {
             "type": "integer",
             "description": "ms, not in the future",
             "x-liftpad-fr": "ms, pas dans le futur"
            },
            "spam": {
             "type": "boolean"
            },
            "referrer": {
             "type": "string"
            }
           },
           "required": [
            "form",
            "data",
            "createdAt"
           ]
          }
         }
        },
        "required": [
         "submissions"
        ]
       },
       "example": {
        "submissions": [
         {
          "id": "abc123",
          "form": "contact",
          "data": {
           "name": "Sam",
           "message": "Hello"
          },
          "createdAt": 1767225600000
         }
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Imported",
      "x-liftpad-fr": "Importés",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "imported": {
           "type": "integer"
          },
          "skipped": {
           "type": "integer"
          }
         },
         "required": [
          "ok",
          "imported",
          "skipped"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/functions": {
   "get": {
    "operationId": "getFunctions",
    "tags": [
     "sites"
    ],
    "summary": "Get the site's functions",
    "description": "Functions are in alpha: only Liftpad operators can deploy them for now.",
    "x-liftpad-fr": {
     "summary": "Obtenir les fonctions du site",
     "description": "Les fonctions sont en alpha : seuls les opérateurs de Liftpad peuvent les déployer pour l'instant."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Functions, or null",
      "x-liftpad-fr": "Fonctions, ou null",
      "content": {
       "application/json": {
        "schema": {
         "oneOf": [
          {
           "$ref": "#/components/schemas/Functions"
          },
          {
           "type": "null"
          }
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/analytics": {
   "get": {
    "operationId": "getAnalytics",
    "tags": [
     "analytics"
    ],
    "summary": "Visitor statistics",
    "x-liftpad-fr": {
     "summary": "Statistiques de visite"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     },
     {
      "name": "days",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "enum": [
        7,
        30,
        90
       ]
      },
      "description": "7, 30 or 90 (default 7)",
      "x-liftpad-fr": "7, 30 ou 90 (7 par défaut)"
     }
    ],
    "responses": {
     "200": {
      "description": "Statistics",
      "x-liftpad-fr": "Statistiques",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Analytics"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "503": {
      "$ref": "#/components/responses/E503"
     }
    }
   }
  },
  "/sites/{name}/ai-build": {
   "post": {
    "operationId": "aiBuildSite",
    "tags": [
     "ai"
    ],
    "summary": "Build a site with AI",
    "description": "Writes, illustrates and builds a complete site from a short brief, as a draft deploy. Costs 100 credits, given back if the job fails. Dashboard session only.",
    "x-liftpad-fr": {
     "summary": "Créer un site par IA",
     "description": "Rédige, illustre et construit un site complet à partir d'une courte description, en déploiement brouillon. Coûte 100 crédits, remis si la tâche échoue. Session du tableau de bord seulement."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Business name",
          "x-liftpad-fr": "Nom de l'entreprise"
         },
         "about": {
          "type": "string",
          "description": "What it does, at least 20 characters",
          "x-liftpad-fr": "Ce qu'elle fait, au moins 20 caractères"
         },
         "services": {
          "type": "string"
         },
         "area": {
          "type": "string"
         },
         "phone": {
          "type": "string"
         },
         "email": {
          "type": "string"
         },
         "address": {
          "type": "string"
         },
         "hours": {
          "type": "string"
         },
         "langs": {
          "type": "array",
          "items": {
           "type": "string",
           "enum": [
            "en",
            "fr"
           ]
          }
         },
         "style": {
          "type": "string",
          "enum": [
           "warm",
           "modern",
           "elegant",
           "bold",
           "natural"
          ]
         }
        },
        "required": [
         "name",
         "about"
        ]
       },
       "example": {
        "name": "Boulangerie Lune",
        "about": "A neighbourhood bakery in Montreal with sourdough and pastries.",
        "langs": [
         "fr",
         "en"
        ],
        "style": "warm"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Queued",
      "x-liftpad-fr": "En file",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "job": {
           "type": "object",
           "properties": {
            "id": {
             "type": "string"
            },
            "kind": {
             "type": "string"
            },
            "status": {
             "type": "string"
            },
            "credits": {
             "type": "integer"
            }
           }
          }
         },
         "required": [
          "job"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/ai-edit": {
   "post": {
    "operationId": "aiEditSite",
    "tags": [
     "ai"
    ],
    "summary": "Change an AI-built site in words",
    "description": "Costs 20 credits, plus 10 with newImages. Dashboard session only.",
    "x-liftpad-fr": {
     "summary": "Modifier en mots un site créé par IA",
     "description": "Coûte 20 crédits, plus 10 avec newImages. Session du tableau de bord seulement."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "developer",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "instruction": {
          "type": "string",
          "description": "5 to 1000 characters",
          "x-liftpad-fr": "5 à 1000 caractères"
         },
         "newImages": {
          "type": "boolean",
          "description": "Draw two new pictures",
          "x-liftpad-fr": "Dessiner deux nouvelles images"
         }
        },
        "required": [
         "instruction"
        ]
       },
       "example": {
        "instruction": "Add our Sunday hours: 9 to 2."
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Queued",
      "x-liftpad-fr": "En file",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "job": {
           "type": "object",
           "properties": {
            "id": {
             "type": "string"
            },
            "kind": {
             "type": "string"
            },
            "status": {
             "type": "string"
            },
            "credits": {
             "type": "integer"
            }
           }
          }
         },
         "required": [
          "job"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "402": {
      "$ref": "#/components/responses/E402"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/sites/{name}/ai": {
   "get": {
    "operationId": "getAiJobs",
    "tags": [
     "ai"
    ],
    "summary": "AI jobs of a site",
    "x-liftpad-fr": {
     "summary": "Tâches IA d'un site"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/SiteName"
     }
    ],
    "responses": {
     "200": {
      "description": "Jobs",
      "x-liftpad-fr": "Tâches",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "aiSite": {
           "type": "boolean",
           "description": "Built with the AI builder",
           "x-liftpad-fr": "Créé avec le créateur IA"
          },
          "jobs": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/AiJob"
           }
          },
          "costs": {
           "type": "object",
           "additionalProperties": {
            "type": "integer"
           }
          },
          "credits": {
           "type": [
            "object",
            "null"
           ],
           "description": "Shown to owners, admins, billing and developers",
           "x-liftpad-fr": "Montré aux propriétaires, administrateurs, facturation et développeurs"
          }
         },
         "required": [
          "aiSite",
          "jobs",
          "costs"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/me": {
   "get": {
    "operationId": "getMe",
    "tags": [
     "account"
    ],
    "summary": "Who am I",
    "description": "The caller, their teams and roles. With a token, roles are what the token may do.",
    "x-liftpad-fr": {
     "summary": "Qui suis-je",
     "description": "L'appelant, ses équipes et ses rôles. Avec un jeton, les rôles sont ce que le jeton peut faire."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "responses": {
     "200": {
      "description": "You",
      "x-liftpad-fr": "Vous",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Me"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "operationId": "updateMe",
    "tags": [
     "account"
    ],
    "summary": "Change your name",
    "x-liftpad-fr": {
     "summary": "Changer votre nom"
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "none",
    "security": [
     {
      "session": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Up to 80 characters",
          "x-liftpad-fr": "Jusqu'à 80 caractères"
         }
        }
       },
       "example": {
        "name": "Sam Tremblay"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Saved",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/me/logout-all": {
   "post": {
    "operationId": "logoutEverywhere",
    "tags": [
     "account"
    ],
    "summary": "Sign out everywhere",
    "description": "Ends every session and cancels every API token you made.",
    "x-liftpad-fr": {
     "summary": "Se déconnecter partout",
     "description": "Termine toutes les sessions et annule tous vos jetons d'API."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "none",
    "security": [
     {
      "session": []
     }
    ],
    "responses": {
     "200": {
      "description": "Signed out",
      "x-liftpad-fr": "Déconnecté",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/me/tokens": {
   "get": {
    "operationId": "listTokens",
    "tags": [
     "account"
    ],
    "summary": "List your API tokens",
    "description": "Names and dates only; a token's value is never shown again.",
    "x-liftpad-fr": {
     "summary": "Lister vos jetons d'API",
     "description": "Noms et dates seulement; la valeur d'un jeton n'est jamais remontrée."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "none",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "responses": {
     "200": {
      "description": "Tokens",
      "x-liftpad-fr": "Jetons",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Token"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "operationId": "createToken",
    "tags": [
     "account"
    ],
    "summary": "Create an API token",
    "description": "Dashboard session only (a token cannot make tokens). access is deploy (sites, deploys, domains) or read. team limits it to one team. days sets the expiry (the dashboard offers 90, 365 or none; at most 730). The token is in this answer only.",
    "x-liftpad-fr": {
     "summary": "Créer un jeton d'API",
     "description": "Session du tableau de bord seulement (un jeton ne peut pas créer de jeton). access vaut deploy (sites, déploiements, domaines) ou read. team le limite à une équipe. days fixe l'expiration (le tableau de bord offre 90, 365 ou aucune; au plus 730). Le jeton n'apparaît que dans cette réponse."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "none",
    "security": [
     {
      "session": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Up to 60 characters",
          "x-liftpad-fr": "Jusqu'à 60 caractères"
         },
         "access": {
          "type": "string",
          "enum": [
           "deploy",
           "read"
          ],
          "default": "deploy"
         },
         "team": {
          "type": "string",
          "description": "Team slug",
          "x-liftpad-fr": "Slug de l'équipe"
         },
         "days": {
          "type": "integer",
          "maximum": 730,
          "description": "Days until it expires; leave out for no expiry",
          "x-liftpad-fr": "Jours avant l'expiration; omettez pour aucune expiration"
         }
        }
       },
       "example": {
        "name": "GitHub Actions",
        "access": "deploy",
        "team": "my-agency",
        "days": 90
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Created",
      "x-liftpad-fr": "Créé",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string"
          },
          "token": {
           "type": "string",
           "description": "lp_... shown once",
           "x-liftpad-fr": "lp_... montré une fois"
          },
          "expiresAt": {
           "type": [
            "integer",
            "null"
           ]
          }
         },
         "required": [
          "id",
          "token",
          "expiresAt"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/me/tokens/{id}": {
   "delete": {
    "operationId": "revokeToken",
    "tags": [
     "account"
    ],
    "summary": "Revoke an API token",
    "x-liftpad-fr": {
     "summary": "Révoquer un jeton d'API"
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "none",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Token id (tok_...)",
      "x-liftpad-fr": "Identifiant du jeton (tok_...)"
     }
    ],
    "responses": {
     "200": {
      "description": "Revoked",
      "x-liftpad-fr": "Révoqué",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams": {
   "get": {
    "operationId": "listTeams",
    "tags": [
     "teams"
    ],
    "summary": "List your teams",
    "x-liftpad-fr": {
     "summary": "Lister vos équipes"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "responses": {
     "200": {
      "description": "Teams",
      "x-liftpad-fr": "Équipes",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Team"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}": {
   "get": {
    "operationId": "getTeam",
    "tags": [
     "teams"
    ],
    "summary": "Get a team",
    "description": "With members and pending invites (invites for those who manage members).",
    "x-liftpad-fr": {
     "summary": "Obtenir une équipe",
     "description": "Avec les membres et les invitations en attente (pour qui gère les membres)."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "responses": {
     "200": {
      "description": "The team",
      "x-liftpad-fr": "L'équipe",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string"
          },
          "slug": {
           "type": "string",
           "example": "my-agency"
          },
          "name": {
           "type": "string"
          },
          "role": {
           "type": "string",
           "enum": [
            "owner",
            "admin",
            "developer",
            "reviewer",
            "billing",
            "viewer"
           ],
           "description": "Your role in the team (for a token: what the token may do)",
           "x-liftpad-fr": "Votre rôle dans l'équipe (pour un jeton : ce qu'il peut faire)"
          },
          "caps": {
           "type": "array",
           "items": {
            "type": "string",
            "enum": [
             "view",
             "deploy",
             "sites",
             "domains",
             "members",
             "billing",
             "team"
            ]
           }
          },
          "scoped": {
           "type": "boolean",
           "description": "You see only some of the team's sites",
           "x-liftpad-fr": "Vous ne voyez que certains sites de l'équipe"
          },
          "plan": {
           "$ref": "#/components/schemas/Plan"
          },
          "billingStatus": {
           "type": [
            "string",
            "null"
           ]
          },
          "billing": {
           "type": [
            "object",
            "null"
           ]
          },
          "trialEndsAt": {
           "type": [
            "integer",
            "null"
           ]
          },
          "currentPeriodEnd": {
           "type": [
            "integer",
            "null"
           ]
          },
          "billingEmail": {
           "type": [
            "string",
            "null"
           ]
          },
          "usage": {
           "type": [
            "object",
            "null"
           ],
           "description": "Sites, domains, members and storage used",
           "x-liftpad-fr": "Sites, domaines, membres et stockage utilisés"
          },
          "members": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "invites": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "roles": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         },
         "required": [
          "slug",
          "members"
         ],
         "additionalProperties": true
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "operationId": "updateTeam",
    "tags": [
     "teams"
    ],
    "summary": "Rename a team or change its billing email",
    "description": "name needs an owner; billingEmail needs an owner or a billing member.",
    "x-liftpad-fr": {
     "summary": "Renommer une équipe ou changer son courriel de facturation",
     "description": "name exige un propriétaire; billingEmail un propriétaire ou un membre facturation."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "owner",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "billingEmail": {
          "type": "string"
         }
        }
       },
       "example": {
        "name": "My Agency"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Saved",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}/invites": {
   "post": {
    "operationId": "inviteMember",
    "tags": [
     "teams"
    ],
    "summary": "Invite someone",
    "description": "A one-time link by email. sites limits a Developer, Reviewer or Team viewer to some sites. Only owners invite owners or billing members.",
    "x-liftpad-fr": {
     "summary": "Inviter une personne",
     "description": "Un lien à usage unique par courriel. sites limite un développeur, réviseur ou observateur à certains sites. Seuls les propriétaires invitent des propriétaires ou des membres facturation."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "admin",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "email": {
          "type": "string"
         },
         "role": {
          "type": "string",
          "enum": [
           "owner",
           "admin",
           "developer",
           "reviewer",
           "billing",
           "viewer"
          ]
         },
         "sites": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "Site names",
          "x-liftpad-fr": "Noms de sites"
         }
        },
        "required": [
         "email",
         "role"
        ]
       },
       "example": {
        "email": "client@example.com",
        "role": "reviewer",
        "sites": [
         "client-site"
        ]
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Invited",
      "x-liftpad-fr": "Invitée",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}/invites/{id}": {
   "delete": {
    "operationId": "revokeInvite",
    "tags": [
     "teams"
    ],
    "summary": "Cancel an invite",
    "x-liftpad-fr": {
     "summary": "Annuler une invitation"
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "admin",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Invite id",
      "x-liftpad-fr": "Identifiant de l'invitation"
     }
    ],
    "responses": {
     "200": {
      "description": "Canceled",
      "x-liftpad-fr": "Annulée",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}/members/{userId}": {
   "patch": {
    "operationId": "updateMember",
    "tags": [
     "teams"
    ],
    "summary": "Change a member's role or sites",
    "description": "sites null removes the site limit. A team always keeps one owner.",
    "x-liftpad-fr": {
     "summary": "Changer le rôle ou les sites d'un membre",
     "description": "sites null retire la limite de sites. Une équipe garde toujours un propriétaire."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "admin",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     },
     {
      "name": "userId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "User id",
      "x-liftpad-fr": "Identifiant de l'utilisateur"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "role": {
          "type": "string",
          "enum": [
           "owner",
           "admin",
           "developer",
           "reviewer",
           "billing",
           "viewer"
          ]
         },
         "sites": {
          "type": [
           "array",
           "null"
          ],
          "items": {
           "type": "string"
          }
         }
        }
       },
       "example": {
        "role": "developer"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Saved",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "operationId": "removeMember",
    "tags": [
     "teams"
    ],
    "summary": "Remove a member (or leave)",
    "description": "Their tokens for this team stop working.",
    "x-liftpad-fr": {
     "summary": "Retirer un membre (ou quitter)",
     "description": "Ses jetons pour cette équipe cessent de fonctionner."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "admin",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     },
     {
      "name": "userId",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "User id (your own to leave)",
      "x-liftpad-fr": "Identifiant de l'utilisateur (le vôtre pour quitter)"
     }
    ],
    "responses": {
     "200": {
      "description": "Removed",
      "x-liftpad-fr": "Retiré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/plans": {
   "get": {
    "operationId": "listPlans",
    "tags": [
     "billing"
    ],
    "summary": "List plans",
    "description": "Prices in CAD per month, taxes extra. No sign-in needed.",
    "x-liftpad-fr": {
     "summary": "Lister les forfaits",
     "description": "Prix en CAD par mois, taxes en sus. Aucune connexion requise."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-role": "none",
    "security": [],
    "responses": {
     "200": {
      "description": "Plans",
      "x-liftpad-fr": "Forfaits",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Plan"
         }
        }
       }
      }
     }
    }
   }
  },
  "/teams/{slug}/billing": {
   "get": {
    "operationId": "getBilling",
    "tags": [
     "billing"
    ],
    "summary": "A team's plan and billing",
    "x-liftpad-fr": {
     "summary": "Forfait et facturation d'une équipe"
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "responses": {
     "200": {
      "description": "Billing",
      "x-liftpad-fr": "Facturation",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "id": {
           "type": "string"
          },
          "slug": {
           "type": "string",
           "example": "my-agency"
          },
          "name": {
           "type": "string"
          },
          "role": {
           "type": "string",
           "enum": [
            "owner",
            "admin",
            "developer",
            "reviewer",
            "billing",
            "viewer"
           ],
           "description": "Your role in the team (for a token: what the token may do)",
           "x-liftpad-fr": "Votre rôle dans l'équipe (pour un jeton : ce qu'il peut faire)"
          },
          "caps": {
           "type": "array",
           "items": {
            "type": "string",
            "enum": [
             "view",
             "deploy",
             "sites",
             "domains",
             "members",
             "billing",
             "team"
            ]
           }
          },
          "scoped": {
           "type": "boolean",
           "description": "You see only some of the team's sites",
           "x-liftpad-fr": "Vous ne voyez que certains sites de l'équipe"
          },
          "plan": {
           "$ref": "#/components/schemas/Plan"
          },
          "billingStatus": {
           "type": [
            "string",
            "null"
           ]
          },
          "billing": {
           "type": [
            "object",
            "null"
           ]
          },
          "trialEndsAt": {
           "type": [
            "integer",
            "null"
           ]
          },
          "currentPeriodEnd": {
           "type": [
            "integer",
            "null"
           ]
          },
          "billingEmail": {
           "type": [
            "string",
            "null"
           ]
          },
          "usage": {
           "type": [
            "object",
            "null"
           ],
           "description": "Sites, domains, members and storage used",
           "x-liftpad-fr": "Sites, domaines, membres et stockage utilisés"
          },
          "canManage": {
           "type": "boolean"
          },
          "plans": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "portalUrl": {
           "type": [
            "string",
            "null"
           ]
          },
          "stripeLinked": {
           "type": "boolean"
          }
         },
         "required": [
          "plans"
         ],
         "additionalProperties": true
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}/credits": {
   "get": {
    "operationId": "getCredits",
    "tags": [
     "billing"
    ],
    "summary": "A team's credits",
    "description": "Balance, costs, packs and the last 30 movements. Packs: 1000 for C$10, 5000 for C$45, 12000 for C$99.",
    "x-liftpad-fr": {
     "summary": "Crédits d'une équipe",
     "description": "Solde, coûts, forfaits de crédits et les 30 derniers mouvements. Ensembles : 1000 pour 10 $, 5000 pour 45 $, 12000 pour 99 $."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "responses": {
     "200": {
      "description": "Credits",
      "x-liftpad-fr": "Crédits",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Credits"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}/credits/checkout": {
   "post": {
    "operationId": "buyCredits",
    "tags": [
     "billing"
    ],
    "summary": "Buy a credit pack",
    "description": "Owners and billing members. Answers with a Stripe checkout address.",
    "x-liftpad-fr": {
     "summary": "Acheter un ensemble de crédits",
     "description": "Propriétaires et membres facturation. Répond avec une adresse de paiement Stripe."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "billing",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "pack": {
          "type": "string",
          "enum": [
           "credits_1000",
           "credits_5000",
           "credits_12000"
          ]
         },
         "saveCard": {
          "type": "boolean",
          "description": "Keep the card for automatic top-ups",
          "x-liftpad-fr": "Garder la carte pour les recharges automatiques"
         }
        },
        "required": [
         "pack"
        ]
       },
       "example": {
        "pack": "credits_1000"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Checkout opened",
      "x-liftpad-fr": "Paiement ouvert",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "checkoutUrl": {
           "type": "string"
          }
         },
         "required": [
          "checkoutUrl"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     },
     "502": {
      "$ref": "#/components/responses/E502"
     },
     "503": {
      "$ref": "#/components/responses/E503"
     }
    }
   }
  },
  "/teams/{slug}/credits/auto": {
   "post": {
    "operationId": "setAutoTopup",
    "tags": [
     "billing"
    ],
    "summary": "Automatic top-ups",
    "description": "Buys a pack when the balance falls below a line, at most 3 times a month. pack null turns it off.",
    "x-liftpad-fr": {
     "summary": "Recharges automatiques",
     "description": "Achète un ensemble quand le solde passe sous un seuil, au plus 3 fois par mois. pack null les désactive."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "billing",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "pack": {
          "type": [
           "string",
           "null"
          ]
         },
         "below": {
          "type": "integer"
         }
        }
       },
       "example": {
        "pack": "credits_1000",
        "below": 100
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Saved",
      "x-liftpad-fr": "Enregistré",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/teams/{slug}/credits/card": {
   "delete": {
    "operationId": "forgetCard",
    "tags": [
     "billing"
    ],
    "summary": "Forget the saved card",
    "x-liftpad-fr": {
     "summary": "Oublier la carte enregistrée"
    },
    "x-liftpad-scopes": [],
    "x-liftpad-session-only": true,
    "x-liftpad-token-error": "session_required",
    "x-liftpad-role": "billing",
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamSlug"
     }
    ],
    "responses": {
     "200": {
      "description": "Removed",
      "x-liftpad-fr": "Retirée",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/audit": {
   "get": {
    "operationId": "listAudit",
    "tags": [
     "audit"
    ],
    "summary": "Activity log",
    "description": "The last 200 actions in your teams (only your sites when you are limited to some).",
    "x-liftpad-fr": {
     "summary": "Journal d'activité",
     "description": "Les 200 dernières actions de vos équipes (seulement vos sites si vous êtes limité à certains)."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     },
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/TeamQuery"
     }
    ],
    "responses": {
     "200": {
      "description": "Entries, newest first",
      "x-liftpad-fr": "Entrées, de la plus récente à la plus ancienne",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/AuditEntry"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/abuse": {
   "post": {
    "operationId": "reportAbuse",
    "tags": [
     "public"
    ],
    "summary": "Report a site hosted on Liftpad",
    "description": "Anyone can report phishing, malware, scams and other abuse. A person at Liftpad reviews every report. Needs the x-liftpad-csrf header and a JSON body.",
    "x-liftpad-fr": {
     "summary": "Signaler un site hébergé sur Liftpad",
     "description": "Tout le monde peut signaler de l'hameçonnage, des logiciels malveillants, des arnaques et d'autres abus. Une personne chez Liftpad lit chaque signalement. Exige l'en-tête x-liftpad-csrf et un corps JSON."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-role": "none",
    "security": [],
    "parameters": [
     {
      "$ref": "#/components/parameters/Csrf"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "url": {
          "type": "string",
          "format": "uri"
         },
         "kind": {
          "type": "string",
          "enum": [
           "phishing",
           "malware",
           "scam",
           "spam",
           "copyright",
           "illegal",
           "other"
          ]
         },
         "details": {
          "type": "string",
          "description": "Up to 2000 characters",
          "x-liftpad-fr": "Jusqu'à 2000 caractères"
         },
         "email": {
          "type": "string",
          "description": "To get an answer",
          "x-liftpad-fr": "Pour recevoir une réponse"
         }
        },
        "required": [
         "url"
        ]
       },
       "example": {
        "url": "https://example.liftpad.ca/login",
        "kind": "phishing",
        "details": "Asks for bank passwords."
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Received",
      "x-liftpad-fr": "Reçu",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "message": {
           "type": "string"
          }
         },
         "required": [
          "ok"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/leads": {
   "post": {
    "operationId": "requestContact",
    "tags": [
     "public"
    ],
    "summary": "Ask Liftpad to contact you",
    "description": "The contact form of liftpad.app. Needs the x-liftpad-csrf header and a JSON body.",
    "x-liftpad-fr": {
     "summary": "Demander à être contacté par Liftpad",
     "description": "Le formulaire de contact de liftpad.app. Exige l'en-tête x-liftpad-csrf et un corps JSON."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-role": "none",
    "security": [],
    "parameters": [
     {
      "$ref": "#/components/parameters/Csrf"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "email": {
          "type": "string"
         },
         "company": {
          "type": "string"
         },
         "sites": {
          "type": "string",
          "enum": [
           "1-3",
           "4-10",
           "11-50",
           "51-150",
           "150+"
          ]
         },
         "message": {
          "type": "string"
         },
         "lang": {
          "type": "string",
          "enum": [
           "en",
           "fr"
          ]
         }
        },
        "required": [
         "name",
         "email"
        ]
       },
       "example": {
        "name": "Sam",
        "email": "sam@example.com",
        "sites": "4-10",
        "lang": "en"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Received",
      "x-liftpad-fr": "Reçu",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ok"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/openapi.json": {
   "get": {
    "operationId": "getOpenApi",
    "tags": [
     "meta"
    ],
    "summary": "This OpenAPI document",
    "description": "Also at https://liftpad.app/openapi.json.",
    "x-liftpad-fr": {
     "summary": "Ce document OpenAPI",
     "description": "Aussi à https://liftpad.app/openapi.json."
    },
    "x-liftpad-scopes": [],
    "x-liftpad-role": "none",
    "security": [],
    "responses": {
     "200": {
      "description": "OpenAPI 3.1",
      "x-liftpad-fr": "OpenAPI 3.1",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/mcp": {
   "post": {
    "operationId": "mcp",
    "tags": [
     "mcp"
    ],
    "summary": "MCP server for AI agents",
    "description": "Model Context Protocol over streamable HTTP, stateless JSON-RPC 2.0 (initialize, ping, tools/list, tools/call; a batch answers its first 20 messages, and messages after the 20th are ignored with no answer). API tokens only, never a cookie. Every tool calls this API with your token, so the same roles and limits apply: a read token can use list_sites, get_site, list_deploys, launch_checks, form_submissions, site_analytics and search_domains; the others need a deploy token. Tools: list_sites, get_site, create_site, list_files, read_file, deploy_changes, launch_checks, list_deploys, publish, form_submissions, site_analytics, search_domains, connect_domain, site_agents_report.",
    "x-liftpad-fr": {
     "summary": "Serveur MCP pour les agents IA",
     "description": "Model Context Protocol en HTTP continu, JSON-RPC 2.0 sans état (initialize, ping, tools/list, tools/call; un lot reçoit une réponse pour ses 20 premiers messages, et les messages après le 20e sont ignorés sans réponse). Jetons d'API seulement, jamais de témoin. Chaque outil appelle cette API avec votre jeton : les mêmes rôles et limites s'appliquent. Un jeton read peut utiliser list_sites, get_site, list_deploys, launch_checks, form_submissions, site_analytics et search_domains; les autres exigent un jeton deploy. Outils : list_sites, get_site, create_site, list_files, read_file, deploy_changes, launch_checks, list_deploys, publish, form_submissions, site_analytics, search_domains, connect_domain, site_agents_report."
    },
    "x-liftpad-scopes": [
     "read"
    ],
    "x-liftpad-role": "any",
    "security": [
     {
      "bearer": []
     }
    ],
    "servers": [
     {
      "url": "https://api.liftpad.app"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "oneOf": [
         {
          "type": "object",
          "properties": {
           "jsonrpc": {
            "const": "2.0"
           },
           "id": {
            "type": [
             "string",
             "integer"
            ]
           },
           "method": {
            "type": "string"
           },
           "params": {
            "type": "object"
           }
          },
          "required": [
           "jsonrpc",
           "method"
          ]
         },
         {
          "type": "array",
          "maxItems": 20,
          "items": {
           "type": "object"
          }
         }
        ]
       },
       "example": {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "tools/call",
        "params": {
         "name": "list_sites",
         "arguments": {}
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON-RPC answer (202 with no body for notifications)",
      "x-liftpad-fr": "Réponse JSON-RPC (202 sans corps pour les notifications)",
      "content": {
       "application/json": {
        "schema": {
         "type": [
          "object",
          "array"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  }
 },
 "webhooks": {
  "deploy.ready": {
   "post": {
    "operationId": "webhookDeployReady",
    "summary": "A deploy finished and its preview works",
    "x-liftpad-fr": {
     "summary": "Un déploiement est terminé et son aperçu fonctionne"
    },
    "description": "Liftpad POSTs this JSON to your https address (10 second timeout, no redirects, sent once). Answer 2xx. After 50 failures in a row the notification pauses.",
    "parameters": [
     {
      "name": "x-liftpad-event",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "enum": [
        "deploy.ready",
        "deploy.published",
        "form.submission",
        "test"
       ]
      },
      "description": "The event",
      "x-liftpad-fr": "L'événement"
     },
     {
      "name": "x-liftpad-delivery",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Unique id of this delivery",
      "x-liftpad-fr": "Identifiant unique de cet envoi"
     },
     {
      "name": "x-liftpad-timestamp",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^\\d+$"
      },
      "description": "Unix time in seconds when it was signed",
      "x-liftpad-fr": "Heure Unix en secondes de la signature"
     },
     {
      "name": "x-liftpad-signature",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^sha256=[a-f0-9]{64}$"
      },
      "description": "sha256= then the hex HMAC-SHA256 of \"<timestamp>.<raw body>\" with the hook's secret",
      "x-liftpad-fr": "sha256= puis le HMAC-SHA256 hexadécimal de \"<timestamp>.<corps brut>\" avec le secret de la notification"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "event": {
          "type": "string",
          "const": "deploy.ready"
         },
         "delivery": {
          "type": "string",
          "description": "Same as x-liftpad-delivery",
          "x-liftpad-fr": "Identique à x-liftpad-delivery"
         },
         "at": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 time",
          "x-liftpad-fr": "Heure ISO 8601"
         },
         "site": {
          "type": "object",
          "properties": {
           "name": {
            "type": "string"
           },
           "url": {
            "type": "string"
           }
          },
          "required": [
           "name",
           "url"
          ]
         },
         "deploy": {
          "type": "object",
          "properties": {
           "id": {
            "type": "string"
           },
           "title": {
            "type": [
             "string",
             "null"
            ]
           },
           "previewUrl": {
            "type": "string"
           },
           "files": {
            "type": "integer"
           }
          },
          "required": [
           "id",
           "previewUrl"
          ]
         }
        },
        "required": [
         "event",
         "delivery",
         "at",
         "site",
         "deploy"
        ]
       },
       "example": {
        "event": "deploy.ready",
        "delivery": "6f1c2a9e-0d4b-4c2e-9a77-3b1f0c2d4e5f",
        "at": "2026-11-05T15:04:05.000Z",
        "site": {
         "name": "my-site",
         "url": "https://my-site.liftpad.ca"
        },
        "deploy": {
         "id": "k2j4h6g8f0d2",
         "title": "First deploy",
         "previewUrl": "https://k2j4h6g8f0d2--my-site.liftpad.ca",
         "files": 12
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Received"
     }
    }
   }
  },
  "deploy.published": {
   "post": {
    "operationId": "webhookDeployPublished",
    "summary": "A deploy went live (also after a rollback)",
    "x-liftpad-fr": {
     "summary": "Un déploiement est en ligne (aussi après un retour arrière)"
    },
    "description": "Liftpad POSTs this JSON to your https address (10 second timeout, no redirects, sent once). Answer 2xx. After 50 failures in a row the notification pauses.",
    "parameters": [
     {
      "name": "x-liftpad-event",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "enum": [
        "deploy.ready",
        "deploy.published",
        "form.submission",
        "test"
       ]
      },
      "description": "The event",
      "x-liftpad-fr": "L'événement"
     },
     {
      "name": "x-liftpad-delivery",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Unique id of this delivery",
      "x-liftpad-fr": "Identifiant unique de cet envoi"
     },
     {
      "name": "x-liftpad-timestamp",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^\\d+$"
      },
      "description": "Unix time in seconds when it was signed",
      "x-liftpad-fr": "Heure Unix en secondes de la signature"
     },
     {
      "name": "x-liftpad-signature",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^sha256=[a-f0-9]{64}$"
      },
      "description": "sha256= then the hex HMAC-SHA256 of \"<timestamp>.<raw body>\" with the hook's secret",
      "x-liftpad-fr": "sha256= puis le HMAC-SHA256 hexadécimal de \"<timestamp>.<corps brut>\" avec le secret de la notification"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "event": {
          "type": "string",
          "const": "deploy.published"
         },
         "delivery": {
          "type": "string",
          "description": "Same as x-liftpad-delivery",
          "x-liftpad-fr": "Identique à x-liftpad-delivery"
         },
         "at": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 time",
          "x-liftpad-fr": "Heure ISO 8601"
         },
         "site": {
          "type": "object",
          "properties": {
           "name": {
            "type": "string"
           },
           "url": {
            "type": "string"
           }
          },
          "required": [
           "name",
           "url"
          ]
         },
         "deploy": {
          "type": "object",
          "properties": {
           "id": {
            "type": "string"
           },
           "title": {
            "type": [
             "string",
             "null"
            ]
           }
          },
          "required": [
           "id"
          ]
         }
        },
        "required": [
         "event",
         "delivery",
         "at",
         "site",
         "deploy"
        ]
       },
       "example": {
        "event": "deploy.published",
        "delivery": "0a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
        "at": "2026-11-05T15:05:00.000Z",
        "site": {
         "name": "my-site",
         "url": "https://www.example.com"
        },
        "deploy": {
         "id": "k2j4h6g8f0d2",
         "title": "First deploy"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Received"
     }
    }
   }
  },
  "form.submission": {
   "post": {
    "operationId": "webhookFormSubmission",
    "summary": "A visitor sent a form (spam is not sent)",
    "x-liftpad-fr": {
     "summary": "Un visiteur a envoyé un formulaire (les indésirables ne sont pas transmis)"
    },
    "description": "Liftpad POSTs this JSON to your https address (10 second timeout, no redirects, sent once). Answer 2xx. After 50 failures in a row the notification pauses.",
    "parameters": [
     {
      "name": "x-liftpad-event",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "enum": [
        "deploy.ready",
        "deploy.published",
        "form.submission",
        "test"
       ]
      },
      "description": "The event",
      "x-liftpad-fr": "L'événement"
     },
     {
      "name": "x-liftpad-delivery",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Unique id of this delivery",
      "x-liftpad-fr": "Identifiant unique de cet envoi"
     },
     {
      "name": "x-liftpad-timestamp",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^\\d+$"
      },
      "description": "Unix time in seconds when it was signed",
      "x-liftpad-fr": "Heure Unix en secondes de la signature"
     },
     {
      "name": "x-liftpad-signature",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^sha256=[a-f0-9]{64}$"
      },
      "description": "sha256= then the hex HMAC-SHA256 of \"<timestamp>.<raw body>\" with the hook's secret",
      "x-liftpad-fr": "sha256= puis le HMAC-SHA256 hexadécimal de \"<timestamp>.<corps brut>\" avec le secret de la notification"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "event": {
          "type": "string",
          "const": "form.submission"
         },
         "delivery": {
          "type": "string",
          "description": "Same as x-liftpad-delivery",
          "x-liftpad-fr": "Identique à x-liftpad-delivery"
         },
         "at": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 time",
          "x-liftpad-fr": "Heure ISO 8601"
         },
         "site": {
          "type": "object",
          "properties": {
           "name": {
            "type": "string"
           },
           "url": {
            "type": "string"
           }
          },
          "required": [
           "name",
           "url"
          ]
         },
         "submission": {
          "type": "object",
          "properties": {
           "id": {
            "type": "string"
           },
           "form": {
            "type": "string"
           },
           "data": {
            "type": "object",
            "additionalProperties": {
             "type": "string"
            }
           },
           "files": {
            "type": "array",
            "items": {
             "type": "string"
            },
            "description": "File names (download them with the API)",
            "x-liftpad-fr": "Noms des fichiers (à télécharger par l'API)"
           },
           "preview": {
            "type": "boolean"
           },
           "createdAt": {
            "type": "integer"
           }
          },
          "required": [
           "id",
           "form",
           "data"
          ]
         }
        },
        "required": [
         "event",
         "delivery",
         "at",
         "site",
         "submission"
        ]
       },
       "example": {
        "event": "form.submission",
        "delivery": "9e8d7c6b-5a4f-4e3d-9c2b-1a0f9e8d7c6b",
        "at": "2026-11-05T15:06:00.000Z",
        "site": {
         "name": "my-site",
         "url": "https://my-site.liftpad.ca"
        },
        "submission": {
         "id": "sub_abc123",
         "form": "contact",
         "data": {
          "name": "Sam",
          "message": "Hello"
         },
         "files": [],
         "preview": false,
         "createdAt": 1793977560000
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Received"
     }
    }
   }
  },
  "test": {
   "post": {
    "operationId": "webhookTest",
    "summary": "Sent by the test button (testHook)",
    "x-liftpad-fr": {
     "summary": "Envoyé par le bouton d'essai (testHook)"
    },
    "description": "Liftpad POSTs this JSON to your https address (10 second timeout, no redirects, sent once). Answer 2xx. After 50 failures in a row the notification pauses.",
    "parameters": [
     {
      "name": "x-liftpad-event",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "enum": [
        "deploy.ready",
        "deploy.published",
        "form.submission",
        "test"
       ]
      },
      "description": "The event",
      "x-liftpad-fr": "L'événement"
     },
     {
      "name": "x-liftpad-delivery",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Unique id of this delivery",
      "x-liftpad-fr": "Identifiant unique de cet envoi"
     },
     {
      "name": "x-liftpad-timestamp",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^\\d+$"
      },
      "description": "Unix time in seconds when it was signed",
      "x-liftpad-fr": "Heure Unix en secondes de la signature"
     },
     {
      "name": "x-liftpad-signature",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^sha256=[a-f0-9]{64}$"
      },
      "description": "sha256= then the hex HMAC-SHA256 of \"<timestamp>.<raw body>\" with the hook's secret",
      "x-liftpad-fr": "sha256= puis le HMAC-SHA256 hexadécimal de \"<timestamp>.<corps brut>\" avec le secret de la notification"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "event": {
          "type": "string",
          "const": "test"
         },
         "delivery": {
          "type": "string",
          "description": "Same as x-liftpad-delivery",
          "x-liftpad-fr": "Identique à x-liftpad-delivery"
         },
         "at": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 time",
          "x-liftpad-fr": "Heure ISO 8601"
         },
         "site": {
          "type": "object",
          "properties": {
           "name": {
            "type": "string"
           },
           "url": {
            "type": "string"
           }
          },
          "required": [
           "name",
           "url"
          ]
         }
        },
        "required": [
         "event",
         "delivery",
         "at",
         "site"
        ]
       },
       "example": {
        "event": "test",
        "delivery": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
        "at": "2026-11-05T15:07:00.000Z",
        "site": {
         "name": "my-site",
         "url": "https://my-site.liftpad.ca"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Received"
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearer": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "lp_...",
    "description": "An API token from the dashboard (Account > API tokens). read or deploy, optionally limited to one team, with an expiry."
   },
   "session": {
    "type": "apiKey",
    "in": "cookie",
    "name": "__Host-lp_session",
    "description": "The dashboard's sign-in cookie. Writes also need the header x-liftpad-csrf: 1."
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "example": "not_found",
      "description": "A short, stable code to branch on (for example not_found, plan_limit, session_required)",
      "x-liftpad-fr": "Un code court et stable (par exemple not_found, plan_limit, session_required)"
     },
     "message": {
      "type": "string",
      "description": "A sentence for people, in English",
      "x-liftpad-fr": "Une phrase pour les personnes, en anglais"
     }
    },
    "required": [
     "error"
    ],
    "additionalProperties": true,
    "description": "Every error answer has this shape. Some add fields, such as missing (finalize) or proof (domains).",
    "x-liftpad-fr": "Toutes les erreurs ont cette forme. Certaines ajoutent des champs, comme missing (finalisation) ou proof (domaines)."
   },
   "Ok": {
    "type": "object",
    "properties": {
     "ok": {
      "type": "boolean",
      "const": true
     }
    },
    "required": [
     "ok"
    ]
   },
   "Site": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "example": "site_a1b2c3d4e5",
      "description": "Site id",
      "x-liftpad-fr": "Identifiant du site"
     },
     "name": {
      "type": "string",
      "example": "my-site",
      "description": "Site name: 3 to 40 characters, a-z, 0-9 and single hyphens",
      "x-liftpad-fr": "Nom du site : 3 à 40 caractères, a-z, 0-9 et traits d'union simples"
     },
     "team_id": {
      "type": [
       "string",
       "null"
      ],
      "description": "Id of the team that owns the site",
      "x-liftpad-fr": "Identifiant de l'équipe propriétaire du site"
     },
     "primary_domain": {
      "type": [
       "string",
       "null"
      ],
      "description": "The custom domain visitors are sent to, or null for the liftpad.ca address",
      "x-liftpad-fr": "Le domaine personnalisé principal, ou null pour l'adresse liftpad.ca"
     },
     "live_deploy_id": {
      "type": [
       "string",
       "null"
      ],
      "description": "The deploy visitors see now, or null when nothing is published",
      "x-liftpad-fr": "Le déploiement en ligne, ou null si rien n'est publié"
     },
     "created_at": {
      "type": "integer",
      "description": "When the site was created (milliseconds since 1970, UTC)",
      "x-liftpad-fr": "Création du site (millisecondes depuis 1970, UTC)"
     },
     "updated_at": {
      "type": "integer",
      "description": "Last change (milliseconds since 1970, UTC)",
      "x-liftpad-fr": "Dernière modification (millisecondes depuis 1970, UTC)"
     },
     "suspended_at": {
      "type": [
       "integer",
       "null"
      ],
      "description": "When Liftpad suspended the site (milliseconds since 1970, UTC), or null",
      "x-liftpad-fr": "Suspension du site par Liftpad (millisecondes depuis 1970, UTC), ou null"
     },
     "functions": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "type": "string"
      },
      "description": "Names of the site's functions, or null",
      "x-liftpad-fr": "Noms des fonctions du site, ou null"
     },
     "access": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "all",
       "previews",
       null
      ],
      "description": "Visitor password scope (all or previews), or null when there is none",
      "x-liftpad-fr": "Portée du mot de passe visiteur (all ou previews), ou null"
     },
     "url": {
      "type": "string",
      "format": "uri",
      "example": "https://my-site.liftpad.ca",
      "description": "The site's address on liftpad.ca",
      "x-liftpad-fr": "L'adresse du site sur liftpad.ca"
     }
    },
    "required": [
     "id",
     "name",
     "url"
    ],
    "additionalProperties": true,
    "description": "A site",
    "x-liftpad-fr": "Un site"
   },
   "SiteDetail": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "example": "site_a1b2c3d4e5",
      "description": "Site id",
      "x-liftpad-fr": "Identifiant du site"
     },
     "name": {
      "type": "string",
      "example": "my-site",
      "description": "Site name: 3 to 40 characters, a-z, 0-9 and single hyphens",
      "x-liftpad-fr": "Nom du site : 3 à 40 caractères, a-z, 0-9 et traits d'union simples"
     },
     "team_id": {
      "type": [
       "string",
       "null"
      ],
      "description": "Id of the team that owns the site",
      "x-liftpad-fr": "Identifiant de l'équipe propriétaire du site"
     },
     "primary_domain": {
      "type": [
       "string",
       "null"
      ],
      "description": "The custom domain visitors are sent to, or null for the liftpad.ca address",
      "x-liftpad-fr": "Le domaine personnalisé principal, ou null pour l'adresse liftpad.ca"
     },
     "live_deploy_id": {
      "type": [
       "string",
       "null"
      ],
      "description": "The deploy visitors see now, or null when nothing is published",
      "x-liftpad-fr": "Le déploiement en ligne, ou null si rien n'est publié"
     },
     "created_at": {
      "type": "integer",
      "description": "When the site was created (milliseconds since 1970, UTC)",
      "x-liftpad-fr": "Création du site (millisecondes depuis 1970, UTC)"
     },
     "updated_at": {
      "type": "integer",
      "description": "Last change (milliseconds since 1970, UTC)",
      "x-liftpad-fr": "Dernière modification (millisecondes depuis 1970, UTC)"
     },
     "suspended_at": {
      "type": [
       "integer",
       "null"
      ],
      "description": "When Liftpad suspended the site (milliseconds since 1970, UTC), or null",
      "x-liftpad-fr": "Suspension du site par Liftpad (millisecondes depuis 1970, UTC), ou null"
     },
     "functions": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "type": "string"
      },
      "description": "Names of the site's functions, or null",
      "x-liftpad-fr": "Noms des fonctions du site, ou null"
     },
     "access": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "all",
       "previews",
       null
      ],
      "description": "Visitor password scope (all or previews), or null when there is none",
      "x-liftpad-fr": "Portée du mot de passe visiteur (all ou previews), ou null"
     },
     "url": {
      "type": "string",
      "format": "uri",
      "example": "https://my-site.liftpad.ca",
      "description": "The site's address on liftpad.ca",
      "x-liftpad-fr": "L'adresse du site sur liftpad.ca"
     },
     "live": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/LiveRecord"
       },
       {
        "type": "null"
       }
      ],
      "description": "The live pointer, or null",
      "x-liftpad-fr": "Le pointeur de mise en ligne, ou null"
     },
     "domains": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "hostname": {
         "type": "string"
        },
        "created_at": {
         "type": "integer"
        }
       }
      },
      "description": "Custom domains connected to the site",
      "x-liftpad-fr": "Domaines personnalisés du site"
     }
    },
    "required": [
     "id",
     "name",
     "url",
     "domains"
    ],
    "additionalProperties": true,
    "description": "A site with its live deploy and domains",
    "x-liftpad-fr": "Un site avec son déploiement en ligne et ses domaines"
   },
   "LiveRecord": {
    "type": "object",
    "properties": {
     "deployId": {
      "type": "string",
      "description": "Live deploy id",
      "x-liftpad-fr": "Déploiement en ligne"
     },
     "generation": {
      "type": "integer",
      "description": "Goes up by one at every publish",
      "x-liftpad-fr": "Augmente de un à chaque publication"
     },
     "publishedAt": {
      "type": "integer",
      "description": "When it was published (milliseconds since 1970, UTC)",
      "x-liftpad-fr": "Date de publication (millisecondes depuis 1970, UTC)"
     }
    },
    "required": [
     "deployId",
     "generation",
     "publishedAt"
    ]
   },
   "Overview": {
    "type": "object",
    "properties": {
     "platform": {
      "type": "string",
      "description": "The dashboard domain",
      "x-liftpad-fr": "Le domaine du tableau de bord"
     },
     "sites": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "string",
         "example": "site_a1b2c3d4e5",
         "description": "Site id",
         "x-liftpad-fr": "Identifiant du site"
        },
        "name": {
         "type": "string",
         "example": "my-site",
         "description": "Site name: 3 to 40 characters, a-z, 0-9 and single hyphens",
         "x-liftpad-fr": "Nom du site : 3 à 40 caractères, a-z, 0-9 et traits d'union simples"
        },
        "team_id": {
         "type": [
          "string",
          "null"
         ],
         "description": "Id of the team that owns the site",
         "x-liftpad-fr": "Identifiant de l'équipe propriétaire du site"
        },
        "primary_domain": {
         "type": [
          "string",
          "null"
         ],
         "description": "The custom domain visitors are sent to, or null for the liftpad.ca address",
         "x-liftpad-fr": "Le domaine personnalisé principal, ou null pour l'adresse liftpad.ca"
        },
        "live_deploy_id": {
         "type": [
          "string",
          "null"
         ],
         "description": "The deploy visitors see now, or null when nothing is published",
         "x-liftpad-fr": "Le déploiement en ligne, ou null si rien n'est publié"
        },
        "created_at": {
         "type": "integer",
         "description": "When the site was created (milliseconds since 1970, UTC)",
         "x-liftpad-fr": "Création du site (millisecondes depuis 1970, UTC)"
        },
        "updated_at": {
         "type": "integer",
         "description": "Last change (milliseconds since 1970, UTC)",
         "x-liftpad-fr": "Dernière modification (millisecondes depuis 1970, UTC)"
        },
        "suspended_at": {
         "type": [
          "integer",
          "null"
         ],
         "description": "When Liftpad suspended the site (milliseconds since 1970, UTC), or null",
         "x-liftpad-fr": "Suspension du site par Liftpad (millisecondes depuis 1970, UTC), ou null"
        },
        "functions": {
         "type": [
          "array",
          "null"
         ],
         "items": {
          "type": "string"
         },
         "description": "Names of the site's functions, or null",
         "x-liftpad-fr": "Noms des fonctions du site, ou null"
        },
        "access": {
         "type": [
          "string",
          "null"
         ],
         "enum": [
          "all",
          "previews",
          null
         ],
         "description": "Visitor password scope (all or previews), or null when there is none",
         "x-liftpad-fr": "Portée du mot de passe visiteur (all ou previews), ou null"
        },
        "url": {
         "type": "string",
         "format": "uri",
         "example": "https://my-site.liftpad.ca",
         "description": "The site's address on liftpad.ca",
         "x-liftpad-fr": "L'adresse du site sur liftpad.ca"
        },
        "team_slug": {
         "type": [
          "string",
          "null"
         ]
        },
        "team_name": {
         "type": [
          "string",
          "null"
         ]
        },
        "health_ok": {
         "type": [
          "integer",
          "null"
         ],
         "description": "1 when the last health check passed, 0 when it failed, null before the first one",
         "x-liftpad-fr": "1 si la dernière vérification est réussie, 0 sinon, null avant la première"
        },
        "health_detail": {
         "type": [
          "object",
          "null"
         ],
         "description": "Details of the last health check",
         "x-liftpad-fr": "Détails de la dernière vérification"
        },
        "health_at": {
         "type": [
          "integer",
          "null"
         ],
         "description": "Last health check (milliseconds since 1970, UTC), or null",
         "x-liftpad-fr": "Dernière vérification (millisecondes depuis 1970, UTC), ou null"
        },
        "deploy_count": {
         "type": "integer"
        },
        "live_title": {
         "type": [
          "string",
          "null"
         ],
         "description": "Message of the live deploy",
         "x-liftpad-fr": "Message du déploiement en ligne"
        },
        "live_published_at": {
         "type": [
          "integer",
          "null"
         ],
         "description": "When the live deploy was published (milliseconds since 1970, UTC), or null",
         "x-liftpad-fr": "Publication du déploiement en ligne (millisecondes depuis 1970, UTC), ou null"
        },
        "live_files": {
         "type": [
          "integer",
          "null"
         ],
         "description": "Files in the live deploy",
         "x-liftpad-fr": "Fichiers du déploiement en ligne"
        },
        "domain_count": {
         "type": "integer"
        },
        "platformUrl": {
         "type": "string",
         "description": "The liftpad.ca address (url is the primary domain when there is one)",
         "x-liftpad-fr": "L'adresse liftpad.ca (url est le domaine principal s'il y en a un)"
        }
       },
       "required": [
        "name",
        "url"
       ],
       "additionalProperties": true
      }
     }
    },
    "required": [
     "platform",
     "sites"
    ]
   },
   "Deploy": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "example": "k2j4h6g8f0d2",
      "description": "Deploy id",
      "x-liftpad-fr": "Identifiant du déploiement"
     },
     "site_id": {
      "type": "string"
     },
     "site_name": {
      "type": "string"
     },
     "team_id": {
      "type": [
       "string",
       "null"
      ]
     },
     "state": {
      "type": "string",
      "enum": [
       "uploading",
       "ready",
       "expired"
      ],
      "description": "uploading until finalized, then ready",
      "x-liftpad-fr": "uploading jusqu'à la finalisation, puis ready"
     },
     "title": {
      "type": [
       "string",
       "null"
      ],
      "description": "The deploy message",
      "x-liftpad-fr": "Le message du déploiement"
     },
     "file_count": {
      "type": "integer"
     },
     "total_size": {
      "type": "integer",
      "description": "Bytes",
      "x-liftpad-fr": "Octets"
     },
     "created_at": {
      "type": "integer",
      "description": "Started (milliseconds since 1970, UTC)",
      "x-liftpad-fr": "Début (millisecondes depuis 1970, UTC)"
     },
     "ready_at": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Finalized (milliseconds since 1970, UTC), or null",
      "x-liftpad-fr": "Finalisation (millisecondes depuis 1970, UTC), ou null"
     },
     "published_at": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Last published (milliseconds since 1970, UTC), or null",
      "x-liftpad-fr": "Dernière publication (millisecondes depuis 1970, UTC), ou null"
     },
     "held": {
      "type": "boolean",
      "description": "True while a Liftpad safety review holds it (it cannot be published)",
      "x-liftpad-fr": "Vrai tant qu'une vérification de sécurité de Liftpad le retient (publication impossible)"
     },
     "required": {
      "type": "array",
      "items": {
       "type": "string",
       "pattern": "^[a-f0-9]{64}$",
       "description": "SHA-256 of the file's bytes, 64 lowercase hex characters",
       "x-liftpad-fr": "SHA-256 du contenu du fichier, 64 caractères hexadécimaux minuscules"
      },
      "description": "Files still to upload (while uploading)",
      "x-liftpad-fr": "Fichiers encore à envoyer (pendant l'envoi)"
     },
     "summary": {
      "oneOf": [
       {
        "type": "object",
        "properties": {
         "files": {
          "type": "integer",
          "description": "Files in the deploy",
          "x-liftpad-fr": "Fichiers du déploiement"
         },
         "redirects": {
          "type": "integer",
          "description": "Redirect rules read from _redirects and netlify.toml",
          "x-liftpad-fr": "Règles de redirection lues dans _redirects et netlify.toml"
         },
         "headers": {
          "type": "integer",
          "description": "Header rules",
          "x-liftpad-fr": "Règles d'en-têtes"
         },
         "forms": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "Forms found in the pages",
          "x-liftpad-fr": "Formulaires trouvés dans les pages"
         },
         "checks": {
          "type": "object",
          "properties": {
           "score": {
            "type": "integer"
           },
           "counts": {
            "type": "object",
            "properties": {
             "error": {
              "type": "integer"
             },
             "warning": {
              "type": "integer"
             },
             "info": {
              "type": "integer"
             }
            },
            "description": "Number of issues per level",
            "x-liftpad-fr": "Nombre de problèmes par niveau"
           },
           "pages": {
            "type": "integer"
           }
          },
          "description": "Launch check summary",
          "x-liftpad-fr": "Résumé des vérifications de lancement"
         },
         "warnings": {
          "type": "array",
          "items": {
           "type": "string"
          },
          "description": "Problems that did not stop the deploy",
          "x-liftpad-fr": "Problèmes qui n'ont pas bloqué le déploiement"
         }
        },
        "description": "What the deploy contains and how its launch checks went",
        "x-liftpad-fr": "Le contenu du déploiement et le résultat des vérifications"
       },
       {
        "type": "null"
       }
      ],
      "description": "Set once ready",
      "x-liftpad-fr": "Présent une fois prêt"
     }
    },
    "required": [
     "id",
     "state",
     "held",
     "required"
    ],
    "additionalProperties": true
   },
   "DeployListItem": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "state": {
      "type": "string",
      "enum": [
       "uploading",
       "ready",
       "expired"
      ]
     },
     "title": {
      "type": [
       "string",
       "null"
      ]
     },
     "file_count": {
      "type": "integer"
     },
     "total_size": {
      "type": "integer"
     },
     "created_at": {
      "type": "integer"
     },
     "ready_at": {
      "type": [
       "integer",
       "null"
      ]
     },
     "published_at": {
      "type": [
       "integer",
       "null"
      ]
     },
     "score": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Launch check score from 0 to 100",
      "x-liftpad-fr": "Note des vérifications de 0 à 100"
     },
     "held": {
      "type": "integer",
      "description": "1 while held for a safety review",
      "x-liftpad-fr": "1 si retenu pour vérification"
     },
     "live": {
      "type": "boolean",
      "description": "True for the deploy visitors see now",
      "x-liftpad-fr": "Vrai pour le déploiement en ligne"
     },
     "previewUrl": {
      "type": "string",
      "format": "uri",
      "description": "Preview address of this exact deploy",
      "x-liftpad-fr": "Adresse d'aperçu de ce déploiement"
     }
    },
    "required": [
     "id",
     "state",
     "live",
     "previewUrl"
    ]
   },
   "DeploySummary": {
    "type": "object",
    "properties": {
     "files": {
      "type": "integer",
      "description": "Files in the deploy",
      "x-liftpad-fr": "Fichiers du déploiement"
     },
     "redirects": {
      "type": "integer",
      "description": "Redirect rules read from _redirects and netlify.toml",
      "x-liftpad-fr": "Règles de redirection lues dans _redirects et netlify.toml"
     },
     "headers": {
      "type": "integer",
      "description": "Header rules",
      "x-liftpad-fr": "Règles d'en-têtes"
     },
     "forms": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Forms found in the pages",
      "x-liftpad-fr": "Formulaires trouvés dans les pages"
     },
     "checks": {
      "type": "object",
      "properties": {
       "score": {
        "type": "integer"
       },
       "counts": {
        "type": "object",
        "properties": {
         "error": {
          "type": "integer"
         },
         "warning": {
          "type": "integer"
         },
         "info": {
          "type": "integer"
         }
        },
        "description": "Number of issues per level",
        "x-liftpad-fr": "Nombre de problèmes par niveau"
       },
       "pages": {
        "type": "integer"
       }
      },
      "description": "Launch check summary",
      "x-liftpad-fr": "Résumé des vérifications de lancement"
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Problems that did not stop the deploy",
      "x-liftpad-fr": "Problèmes qui n'ont pas bloqué le déploiement"
     }
    },
    "description": "What the deploy contains and how its launch checks went",
    "x-liftpad-fr": "Le contenu du déploiement et le résultat des vérifications"
   },
   "CheckReport": {
    "type": "object",
    "properties": {
     "v": {
      "type": "integer"
     },
     "score": {
      "type": "integer",
      "description": "0 to 100",
      "x-liftpad-fr": "0 à 100"
     },
     "pages": {
      "type": "integer",
      "description": "HTML pages read",
      "x-liftpad-fr": "Pages HTML lues"
     },
     "counts": {
      "type": "object",
      "properties": {
       "error": {
        "type": "integer"
       },
       "warning": {
        "type": "integer"
       },
       "info": {
        "type": "integer"
       }
      },
      "description": "Number of issues per level",
      "x-liftpad-fr": "Nombre de problèmes par niveau"
     },
     "issues": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "level": {
         "type": "string",
         "enum": [
          "error",
          "warning",
          "info"
         ]
        },
        "code": {
         "type": "string",
         "description": "Stable code, for example broken_link or missing_alt",
         "x-liftpad-fr": "Code stable, par exemple broken_link ou missing_alt"
        },
        "page": {
         "type": [
          "string",
          "null"
         ],
         "description": "The page, or null for the whole site",
         "x-liftpad-fr": "La page, ou null pour tout le site"
        },
        "detail": {
         "type": "string"
        },
        "ref": {
         "type": "string",
         "description": "The file the issue is about, when there is one",
         "x-liftpad-fr": "Le fichier concerné, s'il y en a un"
        }
       },
       "required": [
        "level",
        "code",
        "page",
        "detail"
       ]
      }
     },
     "truncated": {
      "type": "boolean",
      "description": "True when the list was cut short",
      "x-liftpad-fr": "Vrai si la liste a été coupée"
     }
    },
    "required": [
     "score",
     "pages",
     "counts",
     "issues"
    ]
   },
   "Manifest": {
    "type": "object",
    "properties": {
     "v": {
      "type": "integer"
     },
     "id": {
      "type": "string",
      "description": "Deploy id",
      "x-liftpad-fr": "Identifiant du déploiement"
     },
     "siteId": {
      "type": "string"
     },
     "createdAt": {
      "type": "integer"
     },
     "files": {
      "type": "object",
      "additionalProperties": {
       "type": "array",
       "prefixItems": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        },
        {
         "type": "string"
        }
       ],
       "items": false
      },
      "description": "Path to [sha256, size, content type]",
      "x-liftpad-fr": "Chemin vers [sha256, taille, type de contenu]"
     },
     "redirects": {
      "type": "array",
      "items": {
       "type": "object"
      },
      "description": "Redirect rules in the order they apply",
      "x-liftpad-fr": "Règles de redirection, dans l'ordre"
     },
     "headers": {
      "type": "array",
      "items": {
       "type": "object"
      },
      "description": "Header rules",
      "x-liftpad-fr": "Règles d'en-têtes"
     },
     "forms": {
      "type": "object",
      "additionalProperties": {
       "type": "object"
      },
      "description": "Forms found in the pages",
      "x-liftpad-fr": "Formulaires trouvés dans les pages"
     }
    },
    "required": [
     "v",
     "id",
     "files",
     "redirects",
     "headers"
    ],
    "additionalProperties": true
   },
   "Domain": {
    "type": "object",
    "properties": {
     "hostname": {
      "type": "string",
      "example": "www.example.com"
     },
     "status": {
      "type": "string",
      "description": "Cloudflare hostname status (active when ready)",
      "x-liftpad-fr": "État du nom d'hôte chez Cloudflare (active quand prêt)"
     },
     "sslStatus": {
      "type": "string",
      "description": "Certificate status (active when ready)",
      "x-liftpad-fr": "État du certificat (active quand prêt)"
     },
     "dnsOk": {
      "type": "boolean",
      "description": "Public DNS points at Liftpad",
      "x-liftpad-fr": "Le DNS public pointe vers Liftpad"
     },
     "records": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "type": {
         "type": "string"
        },
        "name": {
         "type": "string"
        },
        "value": {
         "type": "string"
        },
        "why": {
         "type": "string"
        }
       }
      },
      "description": "DNS records to add at the domain's DNS host",
      "x-liftpad-fr": "Enregistrements DNS à ajouter chez l'hébergeur DNS"
     },
     "createdAt": {
      "type": "integer"
     },
     "mainWhenReady": {
      "type": "boolean",
      "description": "Becomes the primary domain once ready",
      "x-liftpad-fr": "Deviendra le domaine principal une fois prêt"
     },
     "verified": {
      "type": "boolean"
     },
     "managed": {
      "type": "boolean",
      "description": "Bought on Liftpad",
      "x-liftpad-fr": "Acheté sur Liftpad"
     },
     "ready": {
      "type": "boolean",
      "description": "DNS, hostname and certificate are all active",
      "x-liftpad-fr": "DNS, nom d'hôte et certificat tous actifs"
     },
     "primary": {
      "type": "boolean"
     }
    },
    "required": [
     "hostname",
     "status",
     "sslStatus",
     "records"
    ],
    "additionalProperties": true
   },
   "DomainOrder": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "domain": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "enum": [
       "awaiting_payment",
       "requested",
       "registering",
       "registered",
       "failed",
       "canceled"
      ]
     },
     "priceCad": {
      "type": "number",
      "description": "First year in CAD, taxes extra (0 when included in the plan)",
      "x-liftpad-fr": "Première année en CAD, taxes en sus (0 si incluse au forfait)"
     },
     "included": {
      "type": "boolean"
     },
     "error": {
      "type": [
       "string",
       "null"
      ]
     },
     "createdAt": {
      "type": "integer"
     },
     "registeredAt": {
      "type": [
       "integer",
       "null"
      ]
     },
     "expiresAt": {
      "type": [
       "integer",
       "null"
      ]
     }
    },
    "required": [
     "id",
     "domain",
     "status"
    ],
    "additionalProperties": true
   },
   "DomainSearch": {
    "type": "object",
    "properties": {
     "query": {
      "type": "string"
     },
     "exact": {
      "type": [
       "string",
       "null"
      ],
      "description": "The full name asked for, when the query was one",
      "x-liftpad-fr": "Le nom complet demandé, si la recherche en était un"
     },
     "currency": {
      "type": "string",
      "const": "CAD"
     },
     "results": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "name": {
         "type": "string"
        },
        "available": {
         "type": "boolean"
        },
        "priceCad": {
         "type": "number",
         "description": "First year, CAD, taxes extra",
         "x-liftpad-fr": "Première année, CAD, taxes en sus"
        },
        "renewCad": {
         "type": "number",
         "description": "Each later year, CAD",
         "x-liftpad-fr": "Chaque année suivante, CAD"
        },
        "includable": {
         "type": "boolean",
         "description": "Covered by the Business plan's included domain",
         "x-liftpad-fr": "Couvert par le domaine inclus du forfait Business"
        },
        "reason": {
         "type": "string",
         "description": "Why a name cannot be had",
         "x-liftpad-fr": "Pourquoi un nom n'est pas offert"
        }
       },
       "required": [
        "name",
        "available"
       ],
       "additionalProperties": true
      }
     }
    },
    "required": [
     "query",
     "results"
    ]
   },
   "Snippet": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Up to 60 characters, unique in the list",
      "x-liftpad-fr": "Jusqu'à 60 caractères, unique dans la liste"
     },
     "where": {
      "type": "string",
      "enum": [
       "head",
       "body"
      ],
      "description": "End of <head> or end of <body>",
      "x-liftpad-fr": "Fin de <head> ou fin de <body>"
     },
     "html": {
      "type": "string",
      "maxLength": 20000,
      "description": "Up to 20 000 characters",
      "x-liftpad-fr": "Jusqu'à 20 000 caractères"
     }
    },
    "required": [
     "name",
     "where",
     "html"
    ]
   },
   "SplitTest": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "deployId": {
      "type": "string",
      "description": "The other deploy some visitors see",
      "x-liftpad-fr": "L'autre déploiement montré à une partie des visiteurs"
     },
     "percent": {
      "type": "integer",
      "minimum": 1,
      "maximum": 99,
      "description": "1 to 99",
      "x-liftpad-fr": "1 à 99"
     },
     "startedAt": {
      "type": "integer"
     }
    },
    "required": [
     "deployId",
     "percent"
    ]
   },
   "Hook": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "example": "hook_a1b2c3d4e5f6"
     },
     "kind": {
      "type": "string",
      "enum": [
       "webhook",
       "slack"
      ]
     },
     "url": {
      "type": "string",
      "description": "Where events are sent (Slack addresses are shown shortened)",
      "x-liftpad-fr": "Où les événements sont envoyés (adresses Slack raccourcies)"
     },
     "events": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "deploy.ready",
        "deploy.published",
        "form.submission"
       ]
      }
     },
     "createdAt": {
      "type": "integer"
     },
     "lastStatus": {
      "type": [
       "integer",
       "null"
      ],
      "description": "HTTP status of the last delivery (0 when it could not connect)",
      "x-liftpad-fr": "Statut HTTP du dernier envoi (0 si la connexion a échoué)"
     },
     "lastAt": {
      "type": [
       "integer",
       "null"
      ]
     },
     "paused": {
      "type": "boolean",
      "description": "True after 50 failed deliveries in a row",
      "x-liftpad-fr": "Vrai après 50 envois ratés de suite"
     }
    },
    "required": [
     "id",
     "kind",
     "url",
     "events"
    ]
   },
   "Form": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "live": {
      "type": "boolean",
      "description": "Found in the live deploy",
      "x-liftpad-fr": "Présent dans le déploiement en ligne"
     },
     "fields": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "honeypot": {
      "type": "boolean"
     },
     "files": {
      "type": "boolean",
      "description": "Has file inputs",
      "x-liftpad-fr": "A des champs de fichier"
     },
     "action": {
      "type": [
       "string",
       "null"
      ],
      "description": "Success page",
      "x-liftpad-fr": "Page de confirmation"
     },
     "submissions": {
      "type": "integer"
     },
     "spam": {
      "type": "integer"
     },
     "last": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Newest submission",
      "x-liftpad-fr": "Envoi le plus récent"
     }
    },
    "required": [
     "name",
     "live",
     "submissions",
     "spam"
    ]
   },
   "Submission": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "form": {
      "type": "string"
     },
     "spam": {
      "type": "boolean"
     },
     "preview": {
      "type": "boolean",
      "description": "Sent from a preview address",
      "x-liftpad-fr": "Envoyé depuis une adresse d'aperçu"
     },
     "deployId": {
      "type": [
       "string",
       "null"
      ]
     },
     "data": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      },
      "description": "Field name to value",
      "x-liftpad-fr": "Nom du champ vers sa valeur"
     },
     "files": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "i": {
         "type": "integer",
         "description": "Index for the download route",
         "x-liftpad-fr": "Index pour la route de téléchargement"
        },
        "field": {
         "type": "string"
        },
        "name": {
         "type": "string"
        },
        "type": {
         "type": "string"
        },
        "size": {
         "type": "integer"
        }
       }
      }
     },
     "referrer": {
      "type": [
       "string",
       "null"
      ]
     },
     "createdAt": {
      "type": "integer"
     }
    },
    "required": [
     "id",
     "form",
     "data",
     "createdAt"
    ]
   },
   "Functions": {
    "type": "object",
    "properties": {
     "routes": {
      "type": "array",
      "items": {
       "type": "object"
      }
     },
     "edge": {
      "type": "array",
      "items": {
       "type": "object"
      }
     },
     "schedules": {
      "type": "array",
      "items": {
       "type": "object"
      }
     },
     "deployedAt": {
      "type": "integer"
     },
     "size": {
      "type": "integer"
     }
    },
    "additionalProperties": true,
    "description": "The site's deployed functions",
    "x-liftpad-fr": "Les fonctions déployées du site"
   },
   "Analytics": {
    "type": "object",
    "properties": {
     "enabled": {
      "type": "boolean",
      "description": "False when analytics are not set up on this Liftpad",
      "x-liftpad-fr": "Faux si les statistiques ne sont pas activées sur ce Liftpad"
     },
     "days": {
      "type": "integer"
     },
     "views": {
      "type": "integer"
     },
     "visitors": {
      "type": "integer"
     },
     "daily": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "day": {
         "type": "string"
        },
        "views": {
         "type": "integer"
        },
        "visitors": {
         "type": "integer"
        }
       }
      }
     },
     "pages": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "path": {
         "type": "string"
        },
        "views": {
         "type": "integer"
        }
       }
      }
     }
    },
    "required": [
     "enabled"
    ],
    "additionalProperties": true,
    "description": "Page views of the live site, without cookies or stored addresses",
    "x-liftpad-fr": "Pages vues du site en ligne, sans témoins ni adresses conservées"
   },
   "AiJob": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "kind": {
      "type": "string",
      "enum": [
       "build",
       "edit"
      ]
     },
     "status": {
      "type": "string",
      "enum": [
       "held",
       "queued",
       "running",
       "done",
       "failed"
      ]
     },
     "step": {
      "type": [
       "string",
       "null"
      ]
     },
     "deployId": {
      "type": [
       "string",
       "null"
      ],
      "description": "The draft deploy it made",
      "x-liftpad-fr": "Le déploiement brouillon créé"
     },
     "error": {
      "type": [
       "string",
       "null"
      ]
     },
     "credits": {
      "type": "integer"
     },
     "createdAt": {
      "type": "integer"
     }
    },
    "required": [
     "id",
     "kind",
     "status"
    ]
   },
   "Me": {
    "type": "object",
    "properties": {
     "kind": {
      "type": "string",
      "enum": [
       "session",
       "token"
      ],
      "description": "How the caller signed in",
      "x-liftpad-fr": "Mode de connexion de l'appelant"
     },
     "user": {
      "type": "object",
      "properties": {
       "id": {
        "type": "string"
       },
       "email": {
        "type": "string"
       },
       "name": {
        "type": [
         "string",
         "null"
        ]
       },
       "totp_enabled": {
        "type": "integer"
       },
       "created_at": {
        "type": "integer"
       },
       "last_login_at": {
        "type": [
         "integer",
         "null"
        ]
       },
       "recovery_left": {
        "type": "integer"
       }
      },
      "required": [
       "email"
      ],
      "additionalProperties": true
     },
     "platformAdmin": {
      "type": "boolean"
     },
     "teams": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Team"
      }
     },
     "roles": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "string"
        },
        "label": {
         "type": "string"
        }
       }
      }
     }
    },
    "required": [
     "kind",
     "user",
     "teams"
    ]
   },
   "Team": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "slug": {
      "type": "string",
      "example": "my-agency"
     },
     "name": {
      "type": "string"
     },
     "role": {
      "type": "string",
      "enum": [
       "owner",
       "admin",
       "developer",
       "reviewer",
       "billing",
       "viewer"
      ],
      "description": "Your role in the team (for a token: what the token may do)",
      "x-liftpad-fr": "Votre rôle dans l'équipe (pour un jeton : ce qu'il peut faire)"
     },
     "caps": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "view",
        "deploy",
        "sites",
        "domains",
        "members",
        "billing",
        "team"
       ]
      }
     },
     "scoped": {
      "type": "boolean",
      "description": "You see only some of the team's sites",
      "x-liftpad-fr": "Vous ne voyez que certains sites de l'équipe"
     },
     "plan": {
      "$ref": "#/components/schemas/Plan"
     },
     "billingStatus": {
      "type": [
       "string",
       "null"
      ]
     },
     "billing": {
      "type": [
       "object",
       "null"
      ]
     },
     "trialEndsAt": {
      "type": [
       "integer",
       "null"
      ]
     },
     "currentPeriodEnd": {
      "type": [
       "integer",
       "null"
      ]
     },
     "billingEmail": {
      "type": [
       "string",
       "null"
      ]
     },
     "usage": {
      "type": [
       "object",
       "null"
      ],
      "description": "Sites, domains, members and storage used",
      "x-liftpad-fr": "Sites, domaines, membres et stockage utilisés"
     }
    },
    "required": [
     "id",
     "slug",
     "name",
     "role",
     "plan"
    ],
    "additionalProperties": true
   },
   "Plan": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "priceCad": {
      "type": "number",
      "description": "Monthly, CAD, taxes extra",
      "x-liftpad-fr": "Par mois, CAD, taxes en sus"
     },
     "sites": {
      "type": "integer"
     },
     "domainsPerSite": {
      "type": "integer"
     },
     "deploysPerDay": {
      "type": "integer"
     },
     "maxDeployBytes": {
      "type": "integer"
     },
     "storageBytes": {
      "type": "integer"
     },
     "formSubmissions": {
      "type": "integer",
      "description": "Per calendar month",
      "x-liftpad-fr": "Par mois civil"
     },
     "aiSuggestions": {
      "type": "integer",
      "description": "Per calendar month",
      "x-liftpad-fr": "Par mois civil"
     },
     "imageTransforms": {
      "type": "integer"
     },
     "includedDomains": {
      "type": "integer",
      "description": "Domain registrations included per year",
      "x-liftpad-fr": "Domaines inclus par année"
     },
     "monthlyCredits": {
      "type": "integer"
     },
     "blurb": {
      "type": "string"
     }
    },
    "required": [
     "id",
     "name",
     "priceCad",
     "sites"
    ],
    "additionalProperties": true
   },
   "Token": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "example": "tok_a1b2c3d4e5"
     },
     "name": {
      "type": "string"
     },
     "access": {
      "type": "string",
      "enum": [
       "read",
       "deploy"
      ]
     },
     "team": {
      "type": [
       "string",
       "null"
      ],
      "description": "Slug of the one team it is limited to, or null",
      "x-liftpad-fr": "Slug de la seule équipe permise, ou null"
     },
     "created_at": {
      "type": "integer"
     },
     "last_used_at": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Updated at most once an hour",
      "x-liftpad-fr": "Mis à jour au plus une fois par heure"
     },
     "expires_at": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Null when it never expires",
      "x-liftpad-fr": "Null s'il n'expire jamais"
     }
    },
    "required": [
     "id",
     "name",
     "access"
    ]
   },
   "Credits": {
    "type": "object",
    "properties": {
     "total": {
      "type": "integer"
     },
     "monthly": {
      "type": "integer",
      "description": "Left from this month's plan credits",
      "x-liftpad-fr": "Reste des crédits mensuels du forfait"
     },
     "bought": {
      "type": "integer"
     },
     "planMonthly": {
      "type": "integer"
     },
     "costs": {
      "type": "object",
      "additionalProperties": {
       "type": "integer"
      },
      "description": "Credits per action",
      "x-liftpad-fr": "Crédits par action"
     },
     "packs": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "string"
        },
        "credits": {
         "type": "integer"
        },
        "priceCad": {
         "type": "number"
        }
       }
      }
     },
     "payments": {
      "type": "boolean",
      "description": "Online payment is open",
      "x-liftpad-fr": "Le paiement en ligne est ouvert"
     },
     "card": {
      "type": [
       "object",
       "null"
      ]
     },
     "auto": {
      "type": [
       "object",
       "null"
      ],
      "description": "Automatic top-up settings",
      "x-liftpad-fr": "Recharge automatique"
     },
     "ledger": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "at": {
         "type": "integer"
        },
        "delta": {
         "type": "integer"
        },
        "kind": {
         "type": "string"
        },
        "note": {
         "type": [
          "string",
          "null"
         ]
        }
       }
      }
     }
    },
    "required": [
     "total",
     "costs",
     "packs"
    ],
    "additionalProperties": true
   },
   "AuditEntry": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer"
     },
     "at": {
      "type": "integer"
     },
     "actor": {
      "type": "string",
      "description": "Email of who did it (or a system name)",
      "x-liftpad-fr": "Courriel de l'auteur (ou un nom de système)"
     },
     "action": {
      "type": "string",
      "example": "deploy.publish"
     },
     "target": {
      "type": [
       "string",
       "null"
      ]
     },
     "detail": {
      "type": [
       "string",
       "null"
      ],
      "description": "JSON text",
      "x-liftpad-fr": "Texte JSON"
     },
     "team_id": {
      "type": [
       "string",
       "null"
      ]
     }
    },
    "required": [
     "id",
     "at",
     "actor",
     "action"
    ],
    "additionalProperties": true
   }
  },
  "parameters": {
   "SiteName": {
    "name": "name",
    "in": "path",
    "required": true,
    "schema": {
     "type": "string",
     "pattern": "^[a-z0-9](?:[a-z0-9-]{1,38}[a-z0-9])$"
    },
    "description": "Site name",
    "x-liftpad-fr": "Nom du site",
    "example": "my-site"
   },
   "DeployId": {
    "name": "id",
    "in": "path",
    "required": true,
    "schema": {
     "type": "string"
    },
    "description": "Deploy id",
    "x-liftpad-fr": "Identifiant du déploiement"
   },
   "Hash": {
    "name": "hash",
    "in": "path",
    "required": true,
    "schema": {
     "type": "string",
     "pattern": "^[a-f0-9]{64}$"
    },
    "description": "SHA-256 of the file, lowercase hex",
    "x-liftpad-fr": "SHA-256 du fichier, hexadécimal minuscule"
   },
   "TeamSlug": {
    "name": "slug",
    "in": "path",
    "required": true,
    "schema": {
     "type": "string"
    },
    "description": "Team slug",
    "x-liftpad-fr": "Slug de l'équipe"
   },
   "TeamQuery": {
    "name": "team",
    "in": "query",
    "required": false,
    "schema": {
     "type": "string"
    },
    "description": "Only this team (slug)",
    "x-liftpad-fr": "Seulement cette équipe (slug)"
   },
   "DeployQuery": {
    "name": "deploy",
    "in": "query",
    "required": false,
    "schema": {
     "type": "string"
    },
    "description": "A deploy id (default: the live deploy)",
    "x-liftpad-fr": "Un déploiement (par défaut : celui en ligne)"
   },
   "Csrf": {
    "name": "x-liftpad-csrf",
    "in": "header",
    "required": true,
    "schema": {
     "type": "string",
     "const": "1"
    },
    "description": "Must be 1 (refuses posts from other web pages)",
    "x-liftpad-fr": "Doit valoir 1 (refuse les envois d'autres pages web)"
   }
  },
  "responses": {
   "E400": {
    "description": "The request is not valid (see error and message)",
    "x-liftpad-fr": "La requête n'est pas valide (voir error et message)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E401": {
    "description": "No valid API token or session",
    "x-liftpad-fr": "Aucun jeton d'API ou session valide",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E402": {
    "description": "A plan limit or billing problem (error: plan_limit, credits, billing)",
    "x-liftpad-fr": "Une limite du forfait ou un problème de facturation (error : plan_limit, credits, billing)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E403": {
    "description": "Not allowed: your role is too low, a token was used where a dashboard session is needed (session_required), or the CSRF header is missing (csrf)",
    "x-liftpad-fr": "Non permis : rôle insuffisant, jeton utilisé là où une session du tableau de bord est requise (session_required), ou en-tête CSRF absent (csrf)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E404": {
    "description": "Not found, or not visible to you",
    "x-liftpad-fr": "Introuvable, ou invisible pour vous",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E409": {
    "description": "Conflicts with the current state (see error)",
    "x-liftpad-fr": "En conflit avec l'état actuel (voir error)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E411": {
    "description": "Content-Length header required",
    "x-liftpad-fr": "En-tête Content-Length requis",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E413": {
    "description": "Too large for the plan or the limits",
    "x-liftpad-fr": "Trop gros pour le forfait ou les limites",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E422": {
    "description": "The AI found no safe answer this time",
    "x-liftpad-fr": "L'IA n'a pas trouvé de réponse sûre cette fois",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E429": {
    "description": "Too many requests (error: rate_limited) or a daily limit (error: deploy_limit)",
    "x-liftpad-fr": "Trop de requêtes (error : rate_limited) ou une limite quotidienne (error : deploy_limit)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E502": {
    "description": "An outside service (Cloudflare, the registrar, Stripe) did not answer; try again",
    "x-liftpad-fr": "Un service externe (Cloudflare, le registraire, Stripe) n'a pas répondu; réessayez",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "E503": {
    "description": "Not available yet on this Liftpad, or for a moment",
    "x-liftpad-fr": "Pas encore offert sur ce Liftpad, ou indisponible un moment",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   }
  }
 }
}