diff --git a/scripts/generate-api-v2.mjs b/scripts/generate-api-v2.mjs
index 41e349d7..dbdee42b 100644
--- a/scripts/generate-api-v2.mjs
+++ b/scripts/generate-api-v2.mjs
@@ -11,437 +11,91 @@
* operations.md — Operations-tagged endpoints
* models.md — all component schemas
*
- * authentication.md and README.md are hand-written; this script does not touch them.
+ * authentication.md, migration.md, and README.md are hand-written; this script
+ * does not touch them.
+ *
+ * The rendering lives in scripts/lib/openapi-docs.mjs, shared with the Hosted
+ * v1 generator.
*/
-import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
-import { join, dirname } from "path";
+import { dirname, join } from "path";
import { fileURLToPath } from "url";
-import yaml from "yaml";
+import { generateApiDocs } from "./lib/openapi-docs.mjs";
const __dirname = dirname(fileURLToPath(import.meta.url));
-const SPEC_PATH = join(__dirname, "../specs/dolthub-v2.yaml");
-const OUT_DIR = join(
- __dirname,
- "../site/dolt/src/content/products/dolthub/api/v2"
-);
-
-const spec = yaml.parse(readFileSync(SPEC_PATH, "utf-8"));
-
-// ---------------------------------------------------------------------------
-// $ref resolution (with cycle guard)
-// ---------------------------------------------------------------------------
-
-function resolveRef(ref) {
- const parts = ref.replace(/^#\//, "").split("/");
- let obj = spec;
- for (const p of parts) obj = obj[p];
- return obj;
-}
-
-function deref(obj, depth = 0) {
- if (depth > 8) return obj; // cycle guard
- if (typeof obj !== "object" || obj === null) return obj;
- if (Array.isArray(obj)) return obj.map((x) => deref(x, depth + 1));
- if ("$ref" in obj) return deref(resolveRef(obj.$ref), depth + 1);
- return Object.fromEntries(
- Object.entries(obj).map(([k, v]) => [k, deref(v, depth + 1)])
- );
-}
-
-function refName(refStr) {
- return refStr?.split("/").pop();
-}
-
-// ---------------------------------------------------------------------------
-// Formatting helpers
-// ---------------------------------------------------------------------------
-
-const METHOD_LABELS = {
- get: "GET",
- post: "POST",
- put: "PUT",
- patch: "PATCH",
- delete: "DELETE",
-};
-
-function escapeMarkdown(str = "") {
- return str.replace(/\|/g, "\\|").replace(/\n+/g, " ").trim();
-}
-
-// Same palette + markup as the hand-written v1alpha1 pages' .api-method /
-// .api-path spans (see DocsLayout.astro), so v2 endpoint headers match.
-function methodSpan(method) {
- const colors = {
- get: "29E3C1",
- post: "6DB0FC",
- patch: "F0A35C",
- put: "F0A35C",
- delete: "EF5350",
- };
- const color = colors[method] ?? "888888";
- const label = METHOD_LABELS[method] ?? method.toUpperCase();
- return `${label}`;
-}
-
-function curlExample(method, path, operation) {
- const lines = [
- `curl -X ${METHOD_LABELS[method] ?? method.toUpperCase()} 'https://www.dolthub.com${path}'`,
- ` -H 'Authorization: Bearer YOUR_TOKEN'`,
- ];
- if (method !== "get" && method !== "delete") {
- lines.push(` -H 'Content-Type: application/json'`);
- const reqBody = operation.requestBody?.content?.["application/json"]?.schema;
- if (reqBody) {
- const resolved = deref(reqBody);
- const required = resolved.required ?? [];
- const props = resolved.properties ?? {};
- const example = Object.fromEntries(
- Object.entries(props)
- .filter(([k]) => required.includes(k))
- .slice(0, 4)
- .map(([k, v]) => {
- const t = v.type ?? (v.enum ? "enum" : "object");
- const ex =
- v.examples?.[0] ??
- v.example ??
- (t === "string" ? `"example_${k}"` : t === "boolean" ? false : 0);
- return [k, ex];
- })
- );
- if (Object.keys(example).length > 0) {
- lines.push(` -d '${JSON.stringify(example)}'`);
- }
- }
- }
- return lines.join(" \\\n");
-}
-
-function parametersSection(params) {
- if (!params?.length) return "";
- const rows = params
- .map((p) => {
- const resolved = deref(p);
- const location = resolved.in ?? "";
- const name = resolved.name ?? "";
- const required = resolved.required ? "yes" : "no";
- const type = resolved.schema?.type ?? "";
- const desc = escapeMarkdown(resolved.description ?? "");
- return `| \`${name}\` | ${location} | ${type} | ${required} | ${desc} |`;
- })
- .join("\n");
- return `\n**Parameters**\n\n| Name | In | Type | Required | Description |\n|------|----|------|----------|-------------|\n${rows}\n`;
-}
-
-function requestBodySection(requestBody) {
- if (!requestBody) return "";
- const schema = requestBody.content?.["application/json"]?.schema;
- if (!schema) return "";
- const resolved = deref(schema);
- const required = resolved.required ?? [];
- const props = resolved.properties ?? {};
- if (!Object.keys(props).length) return "";
- const rows = Object.entries(props)
- .map(([k, v]) => {
- const req = required.includes(k) ? "yes" : "no";
- const type = v.type ?? (v.$ref ? refName(v.$ref) : "object");
- const desc = escapeMarkdown(v.description ?? "");
- return `| \`${k}\` | ${type} | ${req} | ${desc} |`;
- })
- .join("\n");
- return `\n**Request body**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n${rows}\n`;
-}
-
-function responseSchemaName(schema) {
- if (!schema) return "";
- if (schema.$ref) return refName(schema.$ref);
- // Common pattern: allOf: [Envelope, { properties: { data: $ref Schema } }]
- if (schema.allOf) {
- for (const s of schema.allOf) {
- if (s.properties?.data?.$ref) return refName(s.properties.data.$ref);
- // List responses: data.items.$ref
- if (s.properties?.data?.items?.$ref)
- return refName(s.properties.data.items.$ref) + "[]";
- }
- }
- return "";
-}
-
-function successExampleBlock(rawResponses) {
- if (!rawResponses) return "";
- const successCode = Object.keys(rawResponses).find((c) => /^2/.test(c));
- if (!successCode) return "";
-
- const rawResp = rawResponses[successCode];
- const resp = rawResp.$ref ? resolveRef(rawResp.$ref) : rawResp;
- const schema = resp.content?.["application/json"]?.schema;
- if (!schema?.allOf) return "";
-
- let dataExample = null;
- let isList = false;
-
- for (const s of schema.allOf) {
- if (s.properties?.data?.$ref) {
- const name = refName(s.properties.data.$ref);
- dataExample = spec.components?.schemas?.[name]?.examples?.[0] ?? null;
- break;
- }
- if (s.properties?.data?.type === "array" && s.properties?.data?.items?.$ref) {
- const name = refName(s.properties.data.items.$ref);
- dataExample = spec.components?.schemas?.[name]?.examples?.[0] ?? null;
- isList = true;
- break;
- }
- }
-
- if (!dataExample) return "";
-
- const body = isList
- ? { data: [dataExample], meta: { next_page_token: "eyJvZmZzZXQiOjI1fQ" } }
- : { data: dataExample };
-
- return `\n**Example response \`${successCode}\`**\n\n\`\`\`json\n${JSON.stringify(body, null, 2)}\n\`\`\`\n`;
-}
-
-function responsesSection(rawResponses) {
- if (!rawResponses) return "";
- const rows = Object.entries(rawResponses)
- .map(([code, rawResp]) => {
- // Resolve top-level $ref (e.g. $ref: "#/components/responses/Unauthorized")
- const resp = rawResp.$ref ? resolveRef(rawResp.$ref) : rawResp;
- const desc = escapeMarkdown(resp.description ?? "");
- const schema = resp.content?.["application/json"]?.schema;
- const name = responseSchemaName(schema);
- const schemaLink = name
- ? `[\`${name}\`](models#model-${name.replace("[]", "").toLowerCase()})`
- : "";
- return `| \`${code}\` | ${desc} | ${schemaLink} |`;
- })
- .join("\n");
- return `\n**Responses**\n\n| Status | Description | Schema |\n|--------|-------------|--------|\n${rows}\n`;
-}
-
-// ---------------------------------------------------------------------------
-// Derive sub-resource label from path (for grouping within the Database page)
-// ---------------------------------------------------------------------------
-function subResource(path) {
+// The Database tag covers every database sub-resource, so its page gets an H2
+// per sub-resource rather than one flat list of ~20 endpoints.
+function databaseSubResource(path) {
// After /databases/{owner}/{database}/...
- const m = path.match(
- /^\/api\/v2\/databases\/\{[^}]+\}\/\{[^}]+\}\/([^/]+)/
- );
+ const m = path.match(/^\/api\/v2\/databases\/\{[^}]+\}\/\{[^}]+\}\/([^/]+)/);
if (m) {
switch (m[1]) {
- case "branches": return "Branches";
- case "tags": return "Tags";
- case "forks": return "Forks";
- case "releases": return "Releases";
+ case "branches":
+ return "Branches";
+ case "tags":
+ return "Tags";
+ case "forks":
+ return "Forks";
+ case "releases":
+ return "Releases";
case "sql":
case "sql-writes":
return "SQL";
- case "pulls": return "Pull Requests";
- case "imports": return "Imports";
- default: return m[1];
+ case "pulls":
+ return "Pull Requests";
+ case "imports":
+ return "Imports";
+ default:
+ return m[1];
}
}
if (path.startsWith("/api/v2/databases")) return "Databases";
return "Other";
}
-// ---------------------------------------------------------------------------
-// Build per-endpoint Markdown block
-// ---------------------------------------------------------------------------
-
-function endpointBlock(method, path, operation, headingLevel = "###") {
- const anchor = `{#${operation.operationId}}`;
- const title = operation.summary
- ? operation.summary.replace(/\.$/, "")
- : `${METHOD_LABELS[method]} ${path}`;
- const heading = `${headingLevel} ${title} ${anchor}\n`;
- const methodPath = `${methodSpan(method)} ${path}\n\n`;
- const description =
- operation.description &&
- operation.description.trim() !== (operation.summary ?? "").trim()
- ? `${operation.description.trim()}\n\n`
- : "";
- const params = parametersSection(operation.parameters);
- const body = requestBodySection(deref(operation.requestBody ?? {}));
- const responses = responsesSection(operation.responses);
- const successExample = successExampleBlock(operation.responses);
- const curl = `\n**Example request**\n\n\`\`\`sh\n${curlExample(method, path, operation)}\n\`\`\`\n`;
- return [heading, methodPath, description, params, body, curl, responses, successExample]
- .filter(Boolean)
- .join("");
-}
-
-// ---------------------------------------------------------------------------
-// Collect operations by tag
-// ---------------------------------------------------------------------------
-
-const byTag = {}; // tag → [{ method, path, operation }]
-
-for (const [path, pathItem] of Object.entries(spec.paths ?? {})) {
- for (const method of [
- "get",
- "post",
- "put",
- "patch",
- "delete",
- "head",
- "options",
- ]) {
- const op = pathItem[method];
- if (!op) continue;
- for (const tag of op.tags ?? ["Untagged"]) {
- if (!byTag[tag]) byTag[tag] = [];
- byTag[tag].push({ method, path, operation: op });
- }
- }
-}
-
-// ---------------------------------------------------------------------------
-// Tag-level page generators
-// ---------------------------------------------------------------------------
-
-function generateTagPage(tag, items, frontmatter) {
- const tagInfo = spec.tags?.find((t) => t.name === tag) ?? {};
- const intro = tagInfo.description ? `${tagInfo.description}\n\n` : "";
-
- // For Database tag, group by sub-resource
- if (tag === "Database") {
- const groups = {};
- for (const item of items) {
- const g = subResource(item.path);
- if (!groups[g]) groups[g] = [];
- groups[g].push(item);
- }
- const order = [
- "Databases",
- "SQL",
- "Branches",
- "Tags",
- "Forks",
- "Releases",
- "Pull Requests",
- "Imports",
- ];
- const sorted = [
- ...order.filter((g) => groups[g]),
- ...Object.keys(groups).filter((g) => !order.includes(g)),
- ];
- const sections = sorted
- .map((g) => {
- const endpoints = groups[g]
- .map((item) =>
- endpointBlock(item.method, item.path, item.operation, "###")
- )
- .join("\n---\n\n");
- return `## ${g}\n\n${endpoints}`;
- })
- .join("\n\n");
- return `${frontmatter}\n\n${intro}${sections}\n`;
- }
-
- // Other tags: flat list
- const content = items
- .map((item) =>
- endpointBlock(item.method, item.path, item.operation, "##")
- )
- .join("\n---\n\n");
- return `${frontmatter}\n\n${intro}${content}\n`;
-}
-
-// ---------------------------------------------------------------------------
-// Models page
-// ---------------------------------------------------------------------------
-
-function schemaBlock(name, schema) {
- const anchor = `{#model-${name.toLowerCase()}}`;
- const heading = `## ${name} ${anchor}\n`;
- const desc = schema.description ? `${schema.description.trim()}\n\n` : "";
-
- if (schema.enum) {
- const descs = schema["x-enum-descriptions"] ?? [];
- const hasDescs = descs.some(Boolean);
- const values = schema.enum
- .map((v, i) =>
- hasDescs
- ? `| \`${v}\` | ${escapeMarkdown(descs[i] ?? "")} |`
- : `| \`${v}\` |`
- )
- .join("\n");
- const header = hasDescs
- ? `| Value | Description |\n|-------|-------------|`
- : `| Value |\n|-------|`;
- return `${heading}${desc}**Enum values**\n\n${header}\n${values}\n`;
- }
-
- const props = schema.properties ?? schema.allOf?.find((s) => s.properties)?.properties;
- if (!props || !Object.keys(props).length) {
- const type = schema.type ?? (schema.allOf ? "object" : "");
- return `${heading}${desc}${type ? `_Type: \`${type}\`_\n` : ""}\n`;
- }
-
- const required = schema.required ?? schema.allOf?.find((s) => s.required)?.required ?? [];
- const rows = Object.entries(props)
- .map(([k, v]) => {
- const req = required.includes(k) ? "yes" : "no";
- const type = v.type ?? (v.$ref ? refName(v.$ref) : v.allOf ? "object" : "object");
- const d = escapeMarkdown(v.description ?? "");
- return `| \`${k}\` | \`${type}\` | ${req} | ${d} |`;
- })
- .join("\n");
-
- return `${heading}${desc}| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n${rows}\n`;
-}
-
-function generateModelsPage() {
- const fm = `---\ntitle: "Models"\ndescription: Request and response schemas for the DoltHub v2 API.\n---\n\n# Models`;
- const schemas = Object.entries(spec.components?.schemas ?? {});
- const blocks = schemas
- .map(([name, schema]) => schemaBlock(name, deref(schema)))
- .join("\n---\n\n");
- return `${fm}\n\nShared request and response types used across the v2 API. See the [error model](#model-problem) for how failures are reported.\n\n${blocks}\n`;
-}
-
-// ---------------------------------------------------------------------------
-// Write output files
-// ---------------------------------------------------------------------------
-
-mkdirSync(OUT_DIR, { recursive: true });
-
-const tagPages = [
- {
- tag: "User",
- file: "user.md",
- frontmatter:
- '---\ntitle: "User"\ndescription: The authenticated user resource in the DoltHub v2 API.\n---\n\n# User',
- },
- {
- tag: "Database",
- file: "database.md",
- frontmatter:
- '---\ntitle: "Database"\ndescription: DoltHub databases, branches, tags, forks, releases, SQL, pull requests, and imports.\n---\n\n# Database',
- },
- {
- tag: "Operations",
- file: "operations.md",
+generateApiDocs({
+ specPath: join(__dirname, "../specs/dolthub-v2.yaml"),
+ outDir: join(__dirname, "../site/dolt/src/content/products/dolthub/api/v2"),
+ tagPages: [
+ {
+ tag: "User",
+ file: "user.md",
+ frontmatter:
+ '---\ntitle: "User"\ndescription: The authenticated user resource in the DoltHub v2 API.\n---\n\n# User',
+ },
+ {
+ tag: "Database",
+ file: "database.md",
+ frontmatter:
+ '---\ntitle: "Database"\ndescription: DoltHub databases, branches, tags, forks, releases, SQL, pull requests, and imports.\n---\n\n# Database',
+ groups: {
+ of: databaseSubResource,
+ order: [
+ "Databases",
+ "SQL",
+ "Branches",
+ "Tags",
+ "Forks",
+ "Releases",
+ "Pull Requests",
+ "Imports",
+ ],
+ },
+ },
+ {
+ tag: "Operations",
+ file: "operations.md",
+ frontmatter:
+ '---\ntitle: "Operations"\ndescription: Long-running async operations in the DoltHub v2 API.\n---\n\n# Operations',
+ },
+ ],
+ models: {
+ file: "models.md",
+ href: "/products/dolthub/api/v2/models",
frontmatter:
- '---\ntitle: "Operations"\ndescription: Long-running async operations in the DoltHub v2 API.\n---\n\n# Operations',
+ '---\ntitle: "Models"\ndescription: Request and response schemas for the DoltHub v2 API.\n---\n\n# Models',
+ intro:
+ "Shared request and response types used across the v2 API. See the [error model](#model-problem) for how failures are reported.",
},
-];
-
-for (const { tag, file, frontmatter } of tagPages) {
- const items = byTag[tag] ?? [];
- if (!items.length) {
- console.warn(`Warning: no endpoints found for tag "${tag}"`);
- continue;
- }
- const content = generateTagPage(tag, items, frontmatter);
- writeFileSync(join(OUT_DIR, file), content);
- console.log(`Wrote ${file} (${items.length} endpoints)`);
-}
-
-const modelsContent = generateModelsPage();
-writeFileSync(join(OUT_DIR, "models.md"), modelsContent);
-console.log(`Wrote models.md (${Object.keys(spec.components?.schemas ?? {}).length} schemas)`);
+});
diff --git a/scripts/generate-hosted-api-v1.mjs b/scripts/generate-hosted-api-v1.mjs
new file mode 100644
index 00000000..4fb913d0
--- /dev/null
+++ b/scripts/generate-hosted-api-v1.mjs
@@ -0,0 +1,51 @@
+#!/usr/bin/env node
+/**
+ * Generates per-tag Markdown pages for the Hosted v1 API from the OpenAPI spec.
+ *
+ * Usage:
+ * node scripts/generate-hosted-api-v1.mjs
+ *
+ * Output: site/dolt/src/content/products/hosted/api/v1/
+ * user.md — User-tagged endpoints
+ * deployment.md — Deployment-tagged endpoints
+ * models.md — all component schemas
+ *
+ * authentication.md and README.md are hand-written; this script does not touch
+ * them.
+ *
+ * The rendering lives in scripts/lib/openapi-docs.mjs, shared with the DoltHub
+ * v2 generator.
+ */
+
+import { dirname, join } from "path";
+import { fileURLToPath } from "url";
+import { generateApiDocs } from "./lib/openapi-docs.mjs";
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+generateApiDocs({
+ specPath: join(__dirname, "../specs/hosted-v1.yaml"),
+ outDir: join(__dirname, "../site/dolt/src/content/products/hosted/api/v1"),
+ tagPages: [
+ {
+ tag: "User",
+ file: "user.md",
+ frontmatter:
+ '---\ntitle: "User"\ndescription: The authenticated user resource in the Hosted v1 API.\n---\n\n# User',
+ },
+ {
+ tag: "Deployment",
+ file: "deployment.md",
+ frontmatter:
+ '---\ntitle: "Deployment"\ndescription: Creating, listing, and reading Hosted Dolt deployments and their instances.\n---\n\n# Deployment',
+ },
+ ],
+ models: {
+ file: "models.md",
+ href: "/products/hosted/api/v1/models",
+ frontmatter:
+ '---\ntitle: "Models"\ndescription: Request and response schemas for the Hosted v1 API.\n---\n\n# Models',
+ intro:
+ "Shared request and response types used across the v1 API. See the [error model](#model-problem) for how failures are reported.",
+ },
+});
diff --git a/scripts/lib/openapi-docs.mjs b/scripts/lib/openapi-docs.mjs
new file mode 100644
index 00000000..a5cf8704
--- /dev/null
+++ b/scripts/lib/openapi-docs.mjs
@@ -0,0 +1,485 @@
+/**
+ * Shared OpenAPI → Markdown docs generator.
+ *
+ * Both the DoltHub v2 API and the Hosted v1 API are defined by OpenAPI 3.1
+ * specs that share an error model (RFC 9457 `Problem`), a success `Envelope`,
+ * and cursor pagination — deliberately, so the two public APIs don't disagree
+ * about the basics. This module holds the rendering that follows from that
+ * shared shape; the per-API scripts supply only what genuinely differs (spec
+ * path, output directory, page list, and any tag-level grouping).
+ *
+ * See scripts/generate-api-v2.mjs and scripts/generate-hosted-api-v1.mjs.
+ */
+
+import { readFileSync, writeFileSync, mkdirSync } from "fs";
+import { join } from "path";
+import yaml from "yaml";
+
+const METHOD_LABELS = {
+ get: "GET",
+ post: "POST",
+ put: "PUT",
+ patch: "PATCH",
+ delete: "DELETE",
+};
+
+// Same palette + markup as the hand-written v1alpha1 pages' .api-method /
+// .api-path spans (see site/shared/layouts/DocsLayout.astro), so generated
+// endpoint headers match the hand-written ones.
+const METHOD_COLORS = {
+ get: "29E3C1",
+ post: "6DB0FC",
+ patch: "F0A35C",
+ put: "F0A35C",
+ delete: "EF5350",
+};
+
+const HTTP_METHODS = [
+ "get",
+ "post",
+ "put",
+ "patch",
+ "delete",
+ "head",
+ "options",
+];
+
+function escapeMarkdown(str = "") {
+ return str.replace(/\|/g, "\\|").replace(/\n+/g, " ").trim();
+}
+
+function refName(refStr) {
+ return refStr?.split("/").pop();
+}
+
+function methodSpan(method) {
+ const color = METHOD_COLORS[method] ?? "888888";
+ const label = METHOD_LABELS[method] ?? method.toUpperCase();
+ return `${label}`;
+}
+
+/**
+ * Builds a renderer bound to one parsed spec. Everything that needs to walk
+ * `$ref`s closes over `spec`, so nothing is passed around explicitly.
+ */
+function createRenderer(spec, { baseUrl, tokenPlaceholder, modelsHref }) {
+ // -------------------------------------------------------------------------
+ // $ref resolution (with cycle guard)
+ // -------------------------------------------------------------------------
+
+ function resolveRef(ref) {
+ const parts = ref.replace(/^#\//, "").split("/");
+ let obj = spec;
+ for (const p of parts) obj = obj[p];
+ return obj;
+ }
+
+ function deref(obj, depth = 0) {
+ if (depth > 8) return obj; // cycle guard
+ if (typeof obj !== "object" || obj === null) return obj;
+ if (Array.isArray(obj)) return obj.map((x) => deref(x, depth + 1));
+ if ("$ref" in obj) return deref(resolveRef(obj.$ref), depth + 1);
+ return Object.fromEntries(
+ Object.entries(obj).map(([k, v]) => [k, deref(v, depth + 1)])
+ );
+ }
+
+ // -------------------------------------------------------------------------
+ // Examples
+ // -------------------------------------------------------------------------
+
+ // OpenAPI 3.1 permits a media type to carry named `examples`. Prefer the one
+ // named `default`, else the first — a hand-written example beats anything
+ // synthesized from the schema.
+ function mediaTypeExample(mediaType) {
+ if (!mediaType) return undefined;
+ const named = mediaType.examples;
+ if (named && typeof named === "object") {
+ const entry = named.default ?? Object.values(named)[0];
+ if (entry && "value" in entry) return entry.value;
+ }
+ return mediaType.example;
+ }
+
+ function requestExample(operation) {
+ const media = operation.requestBody?.content?.["application/json"];
+ const authored = mediaTypeExample(media);
+ if (authored !== undefined) return authored;
+
+ // Fall back to a minimal object built from the required properties.
+ const schema = media?.schema;
+ if (!schema) return undefined;
+ const resolved = deref(schema);
+ const required = resolved.required ?? [];
+ const props = resolved.properties ?? {};
+ const example = Object.fromEntries(
+ Object.entries(props)
+ .filter(([k]) => required.includes(k))
+ .slice(0, 4)
+ .map(([k, v]) => {
+ const t = v.type ?? (v.enum ? "enum" : "object");
+ const ex =
+ v.examples?.[0] ??
+ v.example ??
+ (t === "string" ? `"example_${k}"` : t === "boolean" ? false : 0);
+ return [k, ex];
+ })
+ );
+ return Object.keys(example).length ? example : undefined;
+ }
+
+ // A value to stand in for a parameter in a curl example: whatever the spec
+ // documents, else the first enum member, else the parameter's own name.
+ function parameterExample(param) {
+ return (
+ param.example ??
+ param.schema?.examples?.[0] ??
+ param.schema?.example ??
+ param.schema?.enum?.[0] ??
+ param.name
+ );
+ }
+
+ // Required query parameters belong in the example URL — without them the
+ // command as printed is a 400 rather than something a reader can paste.
+ // Optional ones are left out so the example shows the minimal call.
+ function requiredQueryString(parameters) {
+ const required = (parameters ?? [])
+ .map((p) => deref(p))
+ .filter((p) => p.in === "query" && p.required);
+ if (!required.length) return "";
+ const pairs = required.map(
+ (p) =>
+ `${encodeURIComponent(p.name)}=${encodeURIComponent(String(parameterExample(p)))}`
+ );
+ return `?${pairs.join("&")}`;
+ }
+
+ function curlExample(method, path, operation) {
+ const url = `${baseUrl}${path}${requiredQueryString(operation.parameters)}`;
+ const lines = [
+ `curl -X ${METHOD_LABELS[method] ?? method.toUpperCase()} '${url}'`,
+ ` -H 'Authorization: Bearer ${tokenPlaceholder}'`,
+ ];
+ if (method !== "get" && method !== "delete") {
+ lines.push(` -H 'Content-Type: application/json'`);
+ const example = requestExample(operation);
+ if (example !== undefined) {
+ lines.push(` -d '${JSON.stringify(example)}'`);
+ }
+ }
+ return lines.join(" \\\n");
+ }
+
+ function successExampleBlock(rawResponses) {
+ if (!rawResponses) return "";
+ const successCode = Object.keys(rawResponses).find((c) => /^2/.test(c));
+ if (!successCode) return "";
+
+ const rawResp = rawResponses[successCode];
+ const resp = rawResp.$ref ? resolveRef(rawResp.$ref) : rawResp;
+ const media = resp.content?.["application/json"];
+
+ // An example authored on the response wins outright — it shows the whole
+ // envelope, including any `meta`, exactly as the API returns it.
+ const authored = mediaTypeExample(media);
+ if (authored !== undefined) {
+ return exampleBlock(successCode, authored);
+ }
+
+ // Otherwise synthesize the envelope from the schema the endpoint narrows
+ // `data` to: allOf: [Envelope, { properties: { data: $ref Schema } }].
+ const schema = media?.schema;
+ if (!schema?.allOf) return "";
+
+ let dataExample = null;
+ let isList = false;
+
+ for (const s of schema.allOf) {
+ if (s.properties?.data?.$ref) {
+ const name = refName(s.properties.data.$ref);
+ dataExample = spec.components?.schemas?.[name]?.examples?.[0] ?? null;
+ break;
+ }
+ if (
+ s.properties?.data?.type === "array" &&
+ s.properties?.data?.items?.$ref
+ ) {
+ const name = refName(s.properties.data.items.$ref);
+ dataExample = spec.components?.schemas?.[name]?.examples?.[0] ?? null;
+ isList = true;
+ break;
+ }
+ }
+
+ if (!dataExample) return "";
+
+ const body = isList
+ ? { data: [dataExample], meta: { next_page_token: "eyJvZmZzZXQiOjI1fQ" } }
+ : { data: dataExample };
+
+ return exampleBlock(successCode, body);
+ }
+
+ function exampleBlock(code, body) {
+ return `\n**Example response \`${code}\`**\n\n\`\`\`json\n${JSON.stringify(body, null, 2)}\n\`\`\`\n`;
+ }
+
+ // -------------------------------------------------------------------------
+ // Endpoint sections
+ // -------------------------------------------------------------------------
+
+ function parametersSection(params) {
+ if (!params?.length) return "";
+ const rows = params
+ .map((p) => {
+ const resolved = deref(p);
+ const location = resolved.in ?? "";
+ const name = resolved.name ?? "";
+ const required = resolved.required ? "yes" : "no";
+ const type = resolved.schema?.type ?? "";
+ const desc = escapeMarkdown(resolved.description ?? "");
+ return `| \`${name}\` | ${location} | ${type} | ${required} | ${desc} |`;
+ })
+ .join("\n");
+ return `\n**Parameters**\n\n| Name | In | Type | Required | Description |\n|------|----|------|----------|-------------|\n${rows}\n`;
+ }
+
+ function requestBodySection(requestBody) {
+ if (!requestBody) return "";
+ const schema = requestBody.content?.["application/json"]?.schema;
+ if (!schema) return "";
+ const resolved = deref(schema);
+ const required = resolved.required ?? [];
+ const props = resolved.properties ?? {};
+ if (!Object.keys(props).length) return "";
+ const rows = Object.entries(props)
+ .map(([k, v]) => {
+ const req = required.includes(k) ? "yes" : "no";
+ const type = v.type ?? (v.$ref ? refName(v.$ref) : "object");
+ const desc = escapeMarkdown(v.description ?? "");
+ return `| \`${k}\` | ${type} | ${req} | ${desc} |`;
+ })
+ .join("\n");
+ return `\n**Request body**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n${rows}\n`;
+ }
+
+ function responseSchemaName(schema) {
+ if (!schema) return "";
+ if (schema.$ref) return refName(schema.$ref);
+ // Common pattern: allOf: [Envelope, { properties: { data: $ref Schema } }]
+ if (schema.allOf) {
+ for (const s of schema.allOf) {
+ if (s.properties?.data?.$ref) return refName(s.properties.data.$ref);
+ // List responses: data.items.$ref
+ if (s.properties?.data?.items?.$ref)
+ return refName(s.properties.data.items.$ref) + "[]";
+ }
+ }
+ return "";
+ }
+
+ function responsesSection(rawResponses) {
+ if (!rawResponses) return "";
+ const rows = Object.entries(rawResponses)
+ .map(([code, rawResp]) => {
+ // Resolve top-level $ref (e.g. $ref: "#/components/responses/Unauthorized")
+ const resp = rawResp.$ref ? resolveRef(rawResp.$ref) : rawResp;
+ const desc = escapeMarkdown(resp.description ?? "");
+ const schema = resp.content?.["application/json"]?.schema;
+ const name = responseSchemaName(schema);
+ const schemaLink = name
+ ? `[\`${name}\`](${modelsHref}#model-${name.replace("[]", "").toLowerCase()})`
+ : "";
+ return `| \`${code}\` | ${desc} | ${schemaLink} |`;
+ })
+ .join("\n");
+ return `\n**Responses**\n\n| Status | Description | Schema |\n|--------|-------------|--------|\n${rows}\n`;
+ }
+
+ function endpointBlock(method, path, operation, headingLevel = "###") {
+ const anchor = `{#${operation.operationId}}`;
+ const title = operation.summary
+ ? operation.summary.replace(/\.$/, "")
+ : `${METHOD_LABELS[method]} ${path}`;
+ const heading = `${headingLevel} ${title} ${anchor}\n`;
+ const methodPath = `${methodSpan(method)} ${path}\n\n`;
+ const description =
+ operation.description &&
+ operation.description.trim() !== (operation.summary ?? "").trim()
+ ? `${operation.description.trim()}\n\n`
+ : "";
+ const params = parametersSection(operation.parameters);
+ const body = requestBodySection(deref(operation.requestBody ?? {}));
+ const responses = responsesSection(operation.responses);
+ const successExample = successExampleBlock(operation.responses);
+ const curl = `\n**Example request**\n\n\`\`\`sh\n${curlExample(method, path, operation)}\n\`\`\`\n`;
+ return [
+ heading,
+ methodPath,
+ description,
+ params,
+ body,
+ curl,
+ responses,
+ successExample,
+ ]
+ .filter(Boolean)
+ .join("");
+ }
+
+ // -------------------------------------------------------------------------
+ // Models
+ // -------------------------------------------------------------------------
+
+ function schemaBlock(name, schema) {
+ const anchor = `{#model-${name.toLowerCase()}}`;
+ const heading = `## ${name} ${anchor}\n`;
+ const desc = schema.description ? `${schema.description.trim()}\n\n` : "";
+
+ if (schema.enum) {
+ const descs = schema["x-enum-descriptions"] ?? [];
+ const hasDescs = descs.some(Boolean);
+ const values = schema.enum
+ .map((v, i) =>
+ hasDescs
+ ? `| \`${v}\` | ${escapeMarkdown(descs[i] ?? "")} |`
+ : `| \`${v}\` |`
+ )
+ .join("\n");
+ const header = hasDescs
+ ? `| Value | Description |\n|-------|-------------|`
+ : `| Value |\n|-------|`;
+ return `${heading}${desc}**Enum values**\n\n${header}\n${values}\n`;
+ }
+
+ const props =
+ schema.properties ?? schema.allOf?.find((s) => s.properties)?.properties;
+ if (!props || !Object.keys(props).length) {
+ const type = schema.type ?? (schema.allOf ? "object" : "");
+ return `${heading}${desc}${type ? `_Type: \`${type}\`_\n` : ""}\n`;
+ }
+
+ const required =
+ schema.required ?? schema.allOf?.find((s) => s.required)?.required ?? [];
+ const rows = Object.entries(props)
+ .map(([k, v]) => {
+ const req = required.includes(k) ? "yes" : "no";
+ const type =
+ v.type ?? (v.$ref ? refName(v.$ref) : v.allOf ? "object" : "object");
+ const d = escapeMarkdown(v.description ?? "");
+ return `| \`${k}\` | \`${type}\` | ${req} | ${d} |`;
+ })
+ .join("\n");
+
+ return `${heading}${desc}| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n${rows}\n`;
+ }
+
+ return { deref, endpointBlock, schemaBlock };
+}
+
+/**
+ * Renders per-tag Markdown pages plus a models page for one OpenAPI spec.
+ *
+ * @param {object} config
+ * @param {string} config.specPath Absolute path to the OpenAPI YAML.
+ * @param {string} config.outDir Absolute path to write pages into.
+ * @param {string} [config.baseUrl] Base URL for curl examples. Defaults to the spec's first server.
+ * @param {string} [config.tokenPlaceholder] Stand-in token in curl examples.
+ * @param {Array} config.tagPages [{ tag, file, frontmatter, groups? }]
+ * `groups` opts a tag into sub-resource sections: { order: string[], of: (path) => string }.
+ * @param {object} config.models { file, href, frontmatter, intro }
+ * `href` is the site-root-relative path of the models page, e.g.
+ * "/products/hosted/api/v1/models". It must be root-relative rather than a
+ * bare "models": these pages build to `/index.html` and are served
+ * from `/`, so a sibling-relative link would resolve one level too
+ * deep. The rehype base-path plugin prefixes the site base at build time.
+ */
+export function generateApiDocs(config) {
+ const {
+ specPath,
+ outDir,
+ tokenPlaceholder = "YOUR_TOKEN",
+ tagPages,
+ models,
+ } = config;
+
+ const spec = yaml.parse(readFileSync(specPath, "utf-8"));
+ const baseUrl = config.baseUrl ?? spec.servers?.[0]?.url ?? "";
+ const { deref, endpointBlock, schemaBlock } = createRenderer(spec, {
+ baseUrl,
+ tokenPlaceholder,
+ modelsHref: models.href,
+ });
+
+ // Collect operations by tag.
+ const byTag = {}; // tag → [{ method, path, operation }]
+ for (const [path, pathItem] of Object.entries(spec.paths ?? {})) {
+ for (const method of HTTP_METHODS) {
+ const op = pathItem[method];
+ if (!op) continue;
+ for (const tag of op.tags ?? ["Untagged"]) {
+ (byTag[tag] ??= []).push({ method, path, operation: op });
+ }
+ }
+ }
+
+ function generateTagPage(tag, items, { frontmatter, groups }) {
+ const tagInfo = spec.tags?.find((t) => t.name === tag) ?? {};
+ const intro = tagInfo.description ? `${tagInfo.description}\n\n` : "";
+
+ // Tags with many endpoints across sub-resources get an H2 per sub-resource
+ // and endpoints at H3; everything else is a flat list of H2 endpoints.
+ if (groups) {
+ const grouped = {};
+ for (const item of items) {
+ (grouped[groups.of(item.path)] ??= []).push(item);
+ }
+ const sorted = [
+ ...groups.order.filter((g) => grouped[g]),
+ ...Object.keys(grouped).filter((g) => !groups.order.includes(g)),
+ ];
+ const sections = sorted
+ .map((g) => {
+ const endpoints = grouped[g]
+ .map((item) =>
+ endpointBlock(item.method, item.path, item.operation, "###")
+ )
+ .join("\n---\n\n");
+ return `## ${g}\n\n${endpoints}`;
+ })
+ .join("\n\n");
+ return `${frontmatter}\n\n${intro}${sections}\n`;
+ }
+
+ const content = items
+ .map((item) => endpointBlock(item.method, item.path, item.operation, "##"))
+ .join("\n---\n\n");
+ return `${frontmatter}\n\n${intro}${content}\n`;
+ }
+
+ mkdirSync(outDir, { recursive: true });
+
+ for (const page of tagPages) {
+ const items = byTag[page.tag] ?? [];
+ if (!items.length) {
+ console.warn(`Warning: no endpoints found for tag "${page.tag}"`);
+ continue;
+ }
+ writeFileSync(
+ join(outDir, page.file),
+ generateTagPage(page.tag, items, page)
+ );
+ console.log(`Wrote ${page.file} (${items.length} endpoints)`);
+ }
+
+ const schemas = Object.entries(spec.components?.schemas ?? {});
+ const blocks = schemas
+ .map(([name, schema]) => schemaBlock(name, deref(schema)))
+ .join("\n---\n\n");
+ writeFileSync(
+ join(outDir, models.file),
+ `${models.frontmatter}\n\n${models.intro}\n\n${blocks}\n`
+ );
+ console.log(`Wrote ${models.file} (${schemas.length} schemas)`);
+}
diff --git a/site/dolt/package.json b/site/dolt/package.json
index bbe282ca..233f4cd2 100644
--- a/site/dolt/package.json
+++ b/site/dolt/package.json
@@ -7,7 +7,8 @@
"dev": "astro dev --port 4321",
"build": "node ../../scripts/check-content-frontmatter.mjs src/content && astro build && cp _redirects dist/_redirects && cp _headers dist/_headers && cp dist/docs/404.html dist/404.html && cp dist/docs/llms.txt dist/llms.txt && npx pagefind --site dist/docs",
"preview": "astro preview --port 4321",
- "generate-api-v2": "node ../../scripts/generate-api-v2.mjs"
+ "generate-api-v2": "node ../../scripts/generate-api-v2.mjs",
+ "generate-hosted-api-v1": "node ../../scripts/generate-hosted-api-v1.mjs"
},
"dependencies": {
"@astrojs/markdown-remark": "^7.2.2",
diff --git a/site/dolt/src/content/architecture/storage-engine.md b/site/dolt/src/content/architecture/storage-engine.md
index 111feb71..05f743ec 100644
--- a/site/dolt/src/content/architecture/storage-engine.md
+++ b/site/dolt/src/content/architecture/storage-engine.md
@@ -54,7 +54,7 @@ Databases are built on top of [Search Trees](https://en.wikipedia.org/wiki/Searc
Dolt is built on a novel Search Tree, closely related to a B-tree, called a Probabilistic B-Tree, or Prolly Tree for short. As far as we can tell, Prolly Trees were [invented by the Noms team specifically for database version control](https://github.com/attic-labs/noms/blob/master/doc/intro) and they also coined the term.
-## B-Trees
+### B-Trees
Most SQL databases you are familiar with, like [Postgres](https://www.postgresql.org/) or [MySQL](https://www.mysql.com/), are built on [B-tree](https://www.dolthub.com/blog/2020-04-01-how-dolt-stores-table-data/#b-tree-review) storage. Tables are represented as a map of primary keys to values and the keys of that map are stored in a B-tree. Values are stored in the leaf nodes.
@@ -66,7 +66,7 @@ However, finding the differences between two B-trees requires scanning both tree
Also, writes to B-trees are not history independent, the order of the writes internally changes the structure of the tree. Thus, storage cannot be easily shared between two versions of the same tree.
-## Prolly Trees
+### Prolly Trees
A Prolly Tree, or Probabilistic B-tree, is a content-addressed B-tree.
@@ -82,7 +82,7 @@ Moreover, sections of the tree that share the same root hash can share storage b
Prolly trees are described in more detail [here](/architecture/storage-engine/prolly-tree).
-## Comparison
+### Comparison
[The Noms documentation](https://github.com/attic-labs/noms/blob/master/doc/intro#some-properties-of-prolly-trees) provides the following useful algorithmic, big O() comparison of B-trees and Prolly Trees:
diff --git a/site/dolt/src/content/introduction/use-cases/audit.md b/site/dolt/src/content/introduction/use-cases/audit.md
index 3fdd0415..de320132 100644
--- a/site/dolt/src/content/introduction/use-cases/audit.md
+++ b/site/dolt/src/content/introduction/use-cases/audit.md
@@ -23,11 +23,11 @@ If you're not ready to switch your primary database to Dolt to get its audit cap
## Dolt replaces...
-## Soft Deletes
+### Soft Deletes
A technique to add audit capability to an existing database is to add [soft deletes](https://www.dolthub.com/blog/2022-11-03-soft-deletes/). Soft delete is the use various techniques to mark data as inactive instead of deleting it. This is strictly worse than a version controlled database for audit purposes. With soft deletes, an operator can still modify data or the application can make mistakes. In Dolt, every write is part of the audit log. It is far more difficult for an operator to change Dolt history.
-## Change Data Capture
+### Change Data Capture
[Change Data Capture](https://www.dolthub.com/blog/2023-03-01-change-data-capture/) is another way to add audit capability to an existing database. Some change data capture techniques are similar to [soft delete](https://www.dolthub.com/blog/2022-11-03-soft-deletes/) strategies. Modern change data capture tools consume replication logs to audit database changes. Dolt can consume the same logs in the [versioned MySQL replica use case](/introduction/use-cases/versioned-replica) producing a simpler and thus, more audit-friendly, change data capture solution.
diff --git a/site/dolt/src/content/introduction/use-cases/configuration-management.md b/site/dolt/src/content/introduction/use-cases/configuration-management.md
index 51a5dbe9..94f00cb4 100644
--- a/site/dolt/src/content/introduction/use-cases/configuration-management.md
+++ b/site/dolt/src/content/introduction/use-cases/configuration-management.md
@@ -24,7 +24,7 @@ This use case is particularly popular in video games where much of the game func
## Dolt replaces...
-## Files in Git
+### Files in Git
Most large configuration files are stored and versioned in Git. If the files get too large they are store in cloud storage and linked to Git using [git-lfs](https://git-lfs.com/). If the files are stored in git-lfs, you lose the ability to diff the contents of the files. Dolt improves the experience by adding query capabilities and large fine-grained diffs to the data stored in configuration files. The diff and merge experience will be greatly improved in Dolt for this type of data.
diff --git a/site/dolt/src/content/introduction/use-cases/data-and-model-quality.md b/site/dolt/src/content/introduction/use-cases/data-and-model-quality.md
index 5d66065e..de86369c 100644
--- a/site/dolt/src/content/introduction/use-cases/data-and-model-quality.md
+++ b/site/dolt/src/content/introduction/use-cases/data-and-model-quality.md
@@ -31,11 +31,11 @@ Lastly, [commits](/concepts/dolt/git/commits), [logs](/concepts/dolt/git/log), a
## Dolt replaces...
-## Unstructured files in cloud storage
+### Unstructured files in cloud storage
It is common practice to store copies of training data or database backups in cloud storage for model reproducibility. A full copy of the data is stored for every training run. This can become quite expensive and limit the amount of models you can reproduce. Dolt stores only the differences between stored versions decreasing the cost of data storage. Additionally, Dolt can produce diffs between versions of training data producing novel model insights.
-## MySQL, Postgres, or other databases
+### MySQL, Postgres, or other databases
Dolt can replace any database used to store and query data. Many of our customers switch from other OLTP databases like MySQL or Postgres to improve data and model quality through versioning. Customers have also switched to Dolt from document databases like MongoDB. Dolt's additional unique features like branches, diffs, and merges allow for human review of data changes and multiple parallel data projects.
diff --git a/site/dolt/src/content/introduction/use-cases/data-sharing.md b/site/dolt/src/content/introduction/use-cases/data-sharing.md
index 892cea59..bf5352dc 100644
--- a/site/dolt/src/content/introduction/use-cases/data-sharing.md
+++ b/site/dolt/src/content/introduction/use-cases/data-sharing.md
@@ -27,11 +27,11 @@ Dolt and DoltHub are also great if vendors share data with you. When you receive
## Dolt replaces...
-## Exchanging Files
+### Exchanging Files
Dolt replaces exchanging flat data files like CSVs via email, FTP servers, or other file transfer techniques. Dolt allows data to maintain schema on exchange including constraints, triggers, and views. This more rich format of exchange reduces transfer errors. Dolt also allows you to change the data to fit your needs and still get updates from your source. Dolt will notify you if your changes [conflict](/concepts/dolt/git/conflicts) with the source.
-## External APIs
+### External APIs
Dolt is ideal for sharing data that does not have an API. But even for data with an API, Dolt is often more convenient. With Dolt, you get all the data and its history. With APIs you often have to assemble the data with multiple API calls. With APIs, the data can change out from under you, whereas with Dolt you can read a version of the data until you are ready to upgrade. DoltHub ships with a [SQL API](/products/dolthub/api/v1alpha1/sql) so you can choose the data sharing solution that is right for your use case.
diff --git a/site/dolt/src/content/introduction/use-cases/manual-data-curation.md b/site/dolt/src/content/introduction/use-cases/manual-data-curation.md
index f580c2e1..05ffffae 100644
--- a/site/dolt/src/content/introduction/use-cases/manual-data-curation.md
+++ b/site/dolt/src/content/introduction/use-cases/manual-data-curation.md
@@ -20,7 +20,7 @@ Dolt is a MySQL compatible database so exporting the manually created data to pr
## Dolt replaces...
-## Spreadsheets
+### Spreadsheets
Dolt replaces Excel or Google Sheets for manual data curation. Versioning features allow for more efficient asynchronous collaboration and human review of data changes. The DoltHub interface is still easy enough for non-technical users to contribute and review data changes.
diff --git a/site/dolt/src/content/introduction/use-cases/offline-first.md b/site/dolt/src/content/introduction/use-cases/offline-first.md
index 5f6980c3..fadc87d0 100644
--- a/site/dolt/src/content/introduction/use-cases/offline-first.md
+++ b/site/dolt/src/content/introduction/use-cases/offline-first.md
@@ -23,7 +23,7 @@ Conflicting writes are surfaced quickly and an operator or software can take add
## Dolt replaces
-## Custom syncing processes
+### Custom syncing processes
Dolt replaces custom code to synchronize your client and server. This code is complicated and hard to get right. The Git [remote](/concepts/dolt/git/remotes) model of clone, fetch, push, and pull is a proven synchronization model. Dolt brings this model to the database allowing you to remove most of your synchronization code.
diff --git a/site/dolt/src/content/introduction/use-cases/vc-your-app.md b/site/dolt/src/content/introduction/use-cases/vc-your-app.md
index 53c45eaf..1e7d0d11 100644
--- a/site/dolt/src/content/introduction/use-cases/vc-your-app.md
+++ b/site/dolt/src/content/introduction/use-cases/vc-your-app.md
@@ -25,11 +25,11 @@ In the past applications that needed these features required [slowly changing di
## Dolt replaces
-## Soft Deletes
+### Soft Deletes
A common technique to version your database is to use [soft deletes](https://www.dolthub.com/blog/2022-11-03-soft-deletes/). When your application would make an update or a delete, you application instead makes an insert and marks the old row invalid. Dolt obviates the need for this technique. You can keep your existing database schema and Dolt ensures every write is non-destructive. Queries against soft deleted rows become Dolt history queries against [system tables](/sql-reference/version-control/dolt-system-tables).
-## Slowly Changing Dimension
+### Slowly Changing Dimension
A more advanced technique for versioning databases is [slowly changing dimension](https://www.dolthub.com/blog/2023-06-22-slowly-changing-dimension/). Slowly Changing Dimension is similar to soft deletes. Additional database columns are added to tables to manage versioning. Dolt is slowly changing dimension on every table by default. Queries involving the slowly changing dimension become Dolt history queries against [system tables](/sql-reference/version-control/dolt-system-tables). Moreover, complicated [merge](/concepts/dolt/git/merge) processes can happen at the database layer. Merges must handled by custom code at the application layer with slowly changing dimension.
diff --git a/site/dolt/src/content/introduction/use-cases/versioned-replica.md b/site/dolt/src/content/introduction/use-cases/versioned-replica.md
index 86d6c941..ead0cecf 100644
--- a/site/dolt/src/content/introduction/use-cases/versioned-replica.md
+++ b/site/dolt/src/content/introduction/use-cases/versioned-replica.md
@@ -25,11 +25,11 @@ Additionally, a Dolt replica can be easily cloned (ie. copied) to a developer's
## Dolt replaces...
-## Backups and Transaction Logs
+### Backups and Transaction Logs
Dolt as a versioned replica becomes your first line of defense against a bad operator query, script, or deployment. Dolt is online and contains the full history of your database. In a disaster you can use diffs to find a bad query and roll it back. Then you can produce a database patch and apply it to production. You do not need to reinstall from a backup and play the transaction log back to the point of the failure, an extremely time consuming process.
-## Change Data Capture
+### Change Data Capture
[Change Data Capture](https://www.dolthub.com/blog/2023-03-01-change-data-capture/) is a way to add a history of data changes to an existing database. Modern change data capture tools consume replication logs to produce database changes in a consumable stream. Dolt can consume the same logs producing a simpler change data capture solution.
diff --git a/site/dolt/src/content/products/dolthub/api/v2/authentication.md b/site/dolt/src/content/products/dolthub/api/v2/authentication.md
index ecec084e..ea69232d 100644
--- a/site/dolt/src/content/products/dolthub/api/v2/authentication.md
+++ b/site/dolt/src/content/products/dolthub/api/v2/authentication.md
@@ -37,4 +37,4 @@ Most write operations and all operations on private databases require authentica
Endpoints that require authentication will return `401 Unauthorized` if no valid credential is supplied, and `403 Forbidden` if the credential is valid but lacks permission.
-See [Models → Problem](models#model-problem) for the error response format.
+See [Models → Problem](/products/dolthub/api/v2/models#model-problem) for the error response format.
diff --git a/site/dolt/src/content/products/dolthub/api/v2/database.md b/site/dolt/src/content/products/dolthub/api/v2/database.md
index a51f3776..06991523 100644
--- a/site/dolt/src/content/products/dolthub/api/v2/database.md
+++ b/site/dolt/src/content/products/dolthub/api/v2/database.md
@@ -37,13 +37,13 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The newly-created database. | [`Database`](models#model-database) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The newly-created database. | [`Database`](/products/dolthub/api/v2/models#model-database) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `201`**
@@ -88,12 +88,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's metadata. | [`Database`](models#model-database) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's metadata. | [`Database`](/products/dolthub/api/v2/models#model-database) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -137,7 +137,7 @@ Public databases are readable without authentication; private databases require
**Example request**
```sh
-curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/sql' \
+curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/sql?ref=main&q=SELECT%20name%2C%20year%20FROM%20jails%20LIMIT%2010' \
-H 'Authorization: Bearer YOUR_TOKEN'
```
@@ -145,12 +145,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/sql' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The query result. SQL-level errors live in `status` + `message`. | [`QueryResult`](models#model-queryresult) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The query result. SQL-level errors live in `status` + `message`. | [`QueryResult`](/products/dolthub/api/v2/models#model-queryresult) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -228,12 +228,12 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/sql' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The read query result. SQL-level errors live in `status` + `message`. | [`QueryResult`](models#model-queryresult) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The read query result. SQL-level errors live in `status` + `message`. | [`QueryResult`](/products/dolthub/api/v2/models#model-queryresult) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -310,13 +310,13 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/sql-wr
| Status | Description | Schema |
|--------|-------------|--------|
-| `202` | The write operation has been accepted and is queued. | [`OperationRef`](models#model-operationref) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `202` | The write operation has been accepted and is queued. | [`OperationRef`](/products/dolthub/api/v2/models#model-operationref) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
## Branches
@@ -346,12 +346,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/branche
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's branches. | [`Branch[]`](models#model-branch) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's branches. | [`Branch[]`](/products/dolthub/api/v2/models#model-branch) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -405,14 +405,14 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/branch
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The newly-created branch. | [`Branch`](models#model-branch) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The newly-created branch. | [`Branch`](/products/dolthub/api/v2/models#model-branch) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `201`**
@@ -454,12 +454,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/tags' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's tags. | [`Tag[]`](models#model-tag) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's tags. | [`Tag[]`](/products/dolthub/api/v2/models#model-tag) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -515,14 +515,14 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/tags'
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The newly-created tag. | [`Tag`](models#model-tag) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The newly-created tag. | [`Tag`](/products/dolthub/api/v2/models#model-tag) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `201`**
@@ -564,12 +564,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/forks'
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's direct fork children (immediate forks only). | [`DatabaseRef[]`](models#model-databaseref) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's direct fork children (immediate forks only). | [`DatabaseRef[]`](/products/dolthub/api/v2/models#model-databaseref) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -621,14 +621,14 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/forks'
| Status | Description | Schema |
|--------|-------------|--------|
-| `202` | The fork operation has been accepted and is queued. | [`OperationRef`](models#model-operationref) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `422` | The request was well-formed but semantically invalid. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `202` | The fork operation has been accepted and is queued. | [`OperationRef`](/products/dolthub/api/v2/models#model-operationref) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `422` | The request was well-formed but semantically invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
## Releases
@@ -658,12 +658,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/release
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's releases. | [`Release[]`](models#model-release) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's releases. | [`Release[]`](/products/dolthub/api/v2/models#model-release) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -723,14 +723,14 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/releas
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The newly-created release. | [`Release`](models#model-release) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The newly-created release. | [`Release`](/products/dolthub/api/v2/models#model-release) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `201`**
@@ -775,12 +775,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls'
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's pull requests. | [`PullSummary[]`](models#model-pullsummary) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's pull requests. | [`PullSummary[]`](/products/dolthub/api/v2/models#model-pullsummary) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -839,14 +839,14 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls'
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The newly-created pull request. | [`Pull`](models#model-pull) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The newly-created pull request. | [`Pull`](/products/dolthub/api/v2/models#model-pull) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `201`**
@@ -904,12 +904,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls/{
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The requested pull request. | [`Pull`](models#model-pull) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The requested pull request. | [`Pull`](/products/dolthub/api/v2/models#model-pull) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -976,13 +976,13 @@ curl -X PATCH 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The updated pull request. | [`Pull`](models#model-pull) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The updated pull request. | [`Pull`](/products/dolthub/api/v2/models#model-pull) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -1040,12 +1040,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls/{
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The pull request's comments. | [`PullComment[]`](models#model-pullcomment) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The pull request's comments. | [`PullComment[]`](/products/dolthub/api/v2/models#model-pullcomment) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
@@ -1101,13 +1101,13 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls/
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The newly-created comment. | [`PullComment`](models#model-pullcomment) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The newly-created comment. | [`PullComment`](/products/dolthub/api/v2/models#model-pullcomment) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `201`**
@@ -1151,14 +1151,14 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/pulls/
| Status | Description | Schema |
|--------|-------------|--------|
-| `202` | The merge operation has been accepted and is queued. | [`OperationRef`](models#model-operationref) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `422` | The request was well-formed but semantically invalid. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `202` | The merge operation has been accepted and is queued. | [`OperationRef`](/products/dolthub/api/v2/models#model-operationref) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `422` | The request was well-formed but semantically invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
## Imports
@@ -1197,13 +1197,13 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/import
| Status | Description | Schema |
|--------|-------------|--------|
-| `201` | The multipart upload session. | [`ImportUpload`](models#model-importupload) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `201` | The multipart upload session. | [`ImportUpload`](/products/dolthub/api/v2/models#model-importupload) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
---
@@ -1252,11 +1252,11 @@ curl -X POST 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/import
| Status | Description | Schema |
|--------|-------------|--------|
-| `202` | The import operation has been accepted and is queued. | [`OperationRef`](models#model-operationref) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `202` | The import operation has been accepted and is queued. | [`OperationRef`](/products/dolthub/api/v2/models#model-operationref) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
diff --git a/site/dolt/src/content/products/dolthub/api/v2/migration.md b/site/dolt/src/content/products/dolthub/api/v2/migration.md
index a21f3287..fad54262 100644
--- a/site/dolt/src/content/products/dolthub/api/v2/migration.md
+++ b/site/dolt/src/content/products/dolthub/api/v2/migration.md
@@ -5,7 +5,7 @@ description: How to migrate your integrations from the DoltHub v1alpha1 API to v
# Migrating from v1alpha1
-This page covers the mechanical changes needed to move an existing v1alpha1 integration to v2. Read it alongside the [v2 overview](../v2) and the per-resource pages.
+This page covers the mechanical changes needed to move an existing v1alpha1 integration to v2. Read it alongside the [v2 overview](/products/dolthub/api/v2) and the per-resource pages.
## 1. Base URL
@@ -54,7 +54,7 @@ v1alpha1 responses are flat and ad-hoc — each endpoint has its own top-level s
## 3. Error model
-v1alpha1 error shapes vary by endpoint. v2 uses [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457) for every non-2xx response. See [Models → Problem](models#model-problem).
+v1alpha1 error shapes vary by endpoint. v2 uses [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457) for every non-2xx response. See [Models → Problem](/products/dolthub/api/v2/models#model-problem).
```json
{
@@ -104,7 +104,7 @@ v2 uses a single unified protocol: any async mutation returns `202` with an `Ope
}
```
-Poll `GET /api/v2/operations/{operation_id}` until `status` is `succeeded` or `failed`. See [Operations](operations#getOperation).
+Poll `GET /api/v2/operations/{operation_id}` until `status` is `succeeded` or `failed`. See [Operations](/products/dolthub/api/v2/operations#getOperation).
```sh
curl 'https://www.dolthub.com/api/v2/operations/owners/dolthub/repos/us-jails/jobs/abc123' \
@@ -117,29 +117,29 @@ curl 'https://www.dolthub.com/api/v2/operations/owners/dolthub/repos/us-jails/jo
| v1alpha1 | v2 |
|---|---|
-| `GET /user` | [`GET /user`](user#getCurrentUser) |
-| `POST /database` | [`POST /databases`](database#createDatabase) |
-| `GET /{owner}/{database}?q=` | [`GET /databases/{owner}/{database}/sql?q=`](database#runSqlReadQuery) |
-| `GET /{owner}/{database}/{ref}?q=` | [`GET /databases/{owner}/{database}/sql?q=&ref=`](database#runSqlReadQuery) |
-| `POST /{owner}/{database}/write/{from_branch}/{to_branch}` | [`POST /databases/{owner}/{database}/sql-writes`](database#runSqlWriteQuery) |
-| `GET /{owner}/{database}/write` | Poll [`GET /operations/{id}`](operations#getOperation) |
-| `GET /{owner}/{database}/forks` | [`GET /databases/{owner}/{database}/forks`](database#listForks) |
-| `GET /{owner}/{database}/branches` | [`GET /databases/{owner}/{database}/branches`](database#listBranches) |
-| `POST /{owner}/{database}/branches` | [`POST /databases/{owner}/{database}/branches`](database#createBranch) |
-| `GET /{owner}/{database}/pulls` | [`GET /databases/{owner}/{database}/pulls`](database#listPulls) |
-| `POST /{owner}/{database}/pulls` | [`POST /databases/{owner}/{database}/pulls`](database#createPull) |
-| `GET /{owner}/{database}/pulls/{id}` | [`GET /databases/{owner}/{database}/pulls/{pull_number}`](database#getPull) |
-| `PATCH /{owner}/{database}/pulls/{id}` | [`PATCH /databases/{owner}/{database}/pulls/{pull_number}`](database#updatePull) |
-| `POST /{owner}/{database}/pulls/{id}/comments` | [`POST /databases/{owner}/{database}/pulls/{pull_number}/comments`](database#createPullComment) |
-| `POST /{owner}/{database}/pulls/{id}/merge` | [`POST /databases/{owner}/{database}/pulls/{pull_number}/merge`](database#mergePull) |
-| `GET /{owner}/{database}/pulls/{id}/merge` | Poll [`GET /operations/{id}`](operations#getOperation) |
-| `GET /{owner}/{database}/releases` | [`GET /databases/{owner}/{database}/releases`](database#listReleases) |
-| `POST /{owner}/{database}/releases` | [`POST /databases/{owner}/{database}/releases`](database#createRelease) |
-| `GET /{owner}/{database}/tags` | [`GET /databases/{owner}/{database}/tags`](database#listTags) |
-| `POST /{owner}/{database}/tags` | [`POST /databases/{owner}/{database}/tags`](database#createTag) |
-| `POST /{owner}/{database}/upload` | [`POST .../imports/uploads`](database#createImportUpload) then [`POST .../imports`](database#createImport) |
-| `GET /{owner}/{database}/upload` | Poll [`GET /operations/{id}`](operations#getOperation) |
-| `POST /fork` | [`POST /databases/{owner}/{database}/forks`](database#createFork) |
-| `GET /fork` | Poll [`GET /operations/{id}`](operations#getOperation) |
-| `GET /{owner}/{database}/jobs` | [`GET /databases/{owner}/{database}/operations`](operations#listOperations) |
-| `GET /users/{username}/operations` | [`GET /databases/{owner}/{database}/operations`](operations#listOperations) |
+| `GET /user` | [`GET /user`](/products/dolthub/api/v2/user#getCurrentUser) |
+| `POST /database` | [`POST /databases`](/products/dolthub/api/v2/database#createDatabase) |
+| `GET /{owner}/{database}?q=` | [`GET /databases/{owner}/{database}/sql?q=`](/products/dolthub/api/v2/database#runSqlReadQuery) |
+| `GET /{owner}/{database}/{ref}?q=` | [`GET /databases/{owner}/{database}/sql?q=&ref=`](/products/dolthub/api/v2/database#runSqlReadQuery) |
+| `POST /{owner}/{database}/write/{from_branch}/{to_branch}` | [`POST /databases/{owner}/{database}/sql-writes`](/products/dolthub/api/v2/database#runSqlWriteQuery) |
+| `GET /{owner}/{database}/write` | Poll [`GET /operations/{id}`](/products/dolthub/api/v2/operations#getOperation) |
+| `GET /{owner}/{database}/forks` | [`GET /databases/{owner}/{database}/forks`](/products/dolthub/api/v2/database#listForks) |
+| `GET /{owner}/{database}/branches` | [`GET /databases/{owner}/{database}/branches`](/products/dolthub/api/v2/database#listBranches) |
+| `POST /{owner}/{database}/branches` | [`POST /databases/{owner}/{database}/branches`](/products/dolthub/api/v2/database#createBranch) |
+| `GET /{owner}/{database}/pulls` | [`GET /databases/{owner}/{database}/pulls`](/products/dolthub/api/v2/database#listPulls) |
+| `POST /{owner}/{database}/pulls` | [`POST /databases/{owner}/{database}/pulls`](/products/dolthub/api/v2/database#createPull) |
+| `GET /{owner}/{database}/pulls/{id}` | [`GET /databases/{owner}/{database}/pulls/{pull_number}`](/products/dolthub/api/v2/database#getPull) |
+| `PATCH /{owner}/{database}/pulls/{id}` | [`PATCH /databases/{owner}/{database}/pulls/{pull_number}`](/products/dolthub/api/v2/database#updatePull) |
+| `POST /{owner}/{database}/pulls/{id}/comments` | [`POST /databases/{owner}/{database}/pulls/{pull_number}/comments`](/products/dolthub/api/v2/database#createPullComment) |
+| `POST /{owner}/{database}/pulls/{id}/merge` | [`POST /databases/{owner}/{database}/pulls/{pull_number}/merge`](/products/dolthub/api/v2/database#mergePull) |
+| `GET /{owner}/{database}/pulls/{id}/merge` | Poll [`GET /operations/{id}`](/products/dolthub/api/v2/operations#getOperation) |
+| `GET /{owner}/{database}/releases` | [`GET /databases/{owner}/{database}/releases`](/products/dolthub/api/v2/database#listReleases) |
+| `POST /{owner}/{database}/releases` | [`POST /databases/{owner}/{database}/releases`](/products/dolthub/api/v2/database#createRelease) |
+| `GET /{owner}/{database}/tags` | [`GET /databases/{owner}/{database}/tags`](/products/dolthub/api/v2/database#listTags) |
+| `POST /{owner}/{database}/tags` | [`POST /databases/{owner}/{database}/tags`](/products/dolthub/api/v2/database#createTag) |
+| `POST /{owner}/{database}/upload` | [`POST .../imports/uploads`](/products/dolthub/api/v2/database#createImportUpload) then [`POST .../imports`](/products/dolthub/api/v2/database#createImport) |
+| `GET /{owner}/{database}/upload` | Poll [`GET /operations/{id}`](/products/dolthub/api/v2/operations#getOperation) |
+| `POST /fork` | [`POST /databases/{owner}/{database}/forks`](/products/dolthub/api/v2/database#createFork) |
+| `GET /fork` | Poll [`GET /operations/{id}`](/products/dolthub/api/v2/operations#getOperation) |
+| `GET /{owner}/{database}/jobs` | [`GET /databases/{owner}/{database}/operations`](/products/dolthub/api/v2/operations#listOperations) |
+| `GET /users/{username}/operations` | [`GET /databases/{owner}/{database}/operations`](/products/dolthub/api/v2/operations#listOperations) |
diff --git a/site/dolt/src/content/products/dolthub/api/v2/operations.md b/site/dolt/src/content/products/dolthub/api/v2/operations.md
index 9b40b697..0cc891b6 100644
--- a/site/dolt/src/content/products/dolthub/api/v2/operations.md
+++ b/site/dolt/src/content/products/dolthub/api/v2/operations.md
@@ -32,12 +32,12 @@ curl -X GET 'https://www.dolthub.com/api/v2/databases/{owner}/{database}/operati
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The database's async operations. | [`Operation[]`](models#model-operation) |
-| `400` | The request was malformed or failed input validation. | [`Problem`](models#model-problem) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The database's async operations. | [`Operation[]`](/products/dolthub/api/v2/models#model-operation) |
+| `400` | The request was malformed or failed input validation. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
---
@@ -64,10 +64,10 @@ curl -X GET 'https://www.dolthub.com/api/v2/operations/{operation_id}' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The current state of the operation. | [`Operation`](models#model-operation) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](models#model-problem) |
-| `404` | The requested resource does not exist. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The current state of the operation. | [`Operation`](/products/dolthub/api/v2/models#model-operation) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `403` | Authenticated, but not permitted to perform this action. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `404` | The requested resource does not exist. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
diff --git a/site/dolt/src/content/products/dolthub/api/v2/user.md b/site/dolt/src/content/products/dolthub/api/v2/user.md
index 62c04811..d204b4fb 100644
--- a/site/dolt/src/content/products/dolthub/api/v2/user.md
+++ b/site/dolt/src/content/products/dolthub/api/v2/user.md
@@ -24,10 +24,10 @@ curl -X GET 'https://www.dolthub.com/api/v2/user' \
| Status | Description | Schema |
|--------|-------------|--------|
-| `200` | The authenticated user's profile. | [`User`](models#model-user) |
-| `401` | Authentication credentials were missing or invalid. | [`Problem`](models#model-problem) |
-| `405` | The HTTP method is not supported for this resource. | [`Problem`](models#model-problem) |
-| `500` | An unexpected server error occurred. | [`Problem`](models#model-problem) |
+| `200` | The authenticated user's profile. | [`User`](/products/dolthub/api/v2/models#model-user) |
+| `401` | Authentication credentials were missing or invalid. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `405` | The HTTP method is not supported for this resource. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
+| `500` | An unexpected server error occurred. | [`Problem`](/products/dolthub/api/v2/models#model-problem) |
**Example response `200`**
diff --git a/site/dolt/src/content/products/dolthub/continuous-integration/README.md b/site/dolt/src/content/products/dolthub/continuous-integration/README.md
index 9f231cce..7a67379e 100644
--- a/site/dolt/src/content/products/dolthub/continuous-integration/README.md
+++ b/site/dolt/src/content/products/dolthub/continuous-integration/README.md
@@ -18,7 +18,7 @@ The following sections will introduce you to how CI works with Dolt, DoltHub and
CI configuration for a DoltHub or DoltLab database is stored in the database itself. At the time of this writing, in order to add CI configuration to a DoltHub or DoltLab database, you will need to have a local Dolt client version >= [v1.45.3](https://github.com/dolthub/dolt/releases/tag/v1.45.3) and will have to clone a copy of the the database. In order to configure CI on the database, you will use Dolt's CI CLI commands.
-## Dolt CI Commands
+### Dolt CI Commands
The primary interface for creating and editing CI configuration in a Dolt database is via the `dolt ci` CLI command. These commands aim to simplify CI configuration in Dolt, so that users do not need to manually interact with the underlying CI tables directly.
@@ -57,7 +57,7 @@ A workflow Job is made up of a series of Steps. A step, in its current form, is
For more information on Steps, please see the [workflow reference](/products/dolthub/continuous-integration/reference).
-## Saved Query
+### Saved Query
A [Saved Query](/sql-reference/version-control/saved-queries) is a SQL query that is stored and versioned in a Dolt database. For the purpose of DoltHub and DoltLab CI, this allows users to write a SQL query that will be executed on command at a later time, during a CI run.
diff --git a/site/dolt/src/content/products/hosted/api/README.md b/site/dolt/src/content/products/hosted/api/README.md
new file mode 100644
index 00000000..989f9ad7
--- /dev/null
+++ b/site/dolt/src/content/products/hosted/api/README.md
@@ -0,0 +1,22 @@
+---
+title: "Hosted Dolt API"
+description: Programmatic access to your Hosted Dolt deployments.
+---
+
+# Hosted Dolt API
+
+Hosted Dolt exposes an HTTP API for managing deployments programmatically — creating them, listing them, and reading their configuration and state from scripts, CI, or your own tooling.
+
+## REST API
+
+- **[v1 API](/products/hosted/api/v1)** — the current generation. An explicit, versioned, OpenAPI-defined contract with consistent HTTP semantics, a single [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) error model, and a uniform response envelope. Start here.
+
+The conventions are deliberately the same as the [DoltHub v2 API](/products/dolthub/api/v2): the same error body, the same success envelope, and the same cursor pagination. If you already integrate with one, the other should feel familiar.
+
+## Scope
+
+The v1 API covers the **control plane** — the deployments themselves. Querying the data *inside* a deployment is not part of it: every deployment exposes a SQL endpoint that you connect to directly with your database credentials, exactly as you would any MySQL or Postgres server. See [Getting Started](/products/hosted/getting-started) for how to connect.
+
+Database credentials are never returned by this API. Reading a deployment tells you its configuration and state, never its secrets.
+
+> **Note:** please send requests to `https://hosted.doltdb.com`.
diff --git a/site/dolt/src/content/products/hosted/api/v1/README.md b/site/dolt/src/content/products/hosted/api/v1/README.md
new file mode 100644
index 00000000..6102f9f4
--- /dev/null
+++ b/site/dolt/src/content/products/hosted/api/v1/README.md
@@ -0,0 +1,101 @@
+---
+title: "Hosted API v1"
+description: The Hosted Dolt v1 API — an explicit, versioned, OpenAPI-defined contract for deployments.
+---
+
+# Hosted API v1
+
+_API version: v1_
+
+The v1 API is the public HTTP surface for the Hosted Dolt control plane. Every endpoint lives under `https://hosted.doltdb.com/api/v1/`.
+
+It is an OpenAPI-defined contract, and commits to:
+
+- Consistent HTTP semantics (correct status codes, idempotent GETs, `202` for work that continues after the response)
+- A single error model ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem details) — see [Problem](/products/hosted/api/v1/models#model-problem)
+- A uniform success [Envelope](/products/hosted/api/v1/models#model-envelope) wrapping every response
+- Cursor pagination on list endpoints
+
+**Scope.** v1 covers the control plane only. Querying the data inside a deployment is not part of this API — connect to the deployment's SQL endpoint directly with your database credentials.
+
+## Authentication
+
+Every endpoint requires a Hosted API token, sent as a bearer token:
+
+```sh
+curl 'https://hosted.doltdb.com/api/v1/user' \
+ -H 'Authorization: Bearer hsat.v1.YOUR_TOKEN_HERE'
+```
+
+See [Authentication](/products/hosted/api/v1/authentication) for how to create and manage tokens.
+
+## All endpoints
+
+### User
+
+| Method | Path | What it does |
+|--------|------|--------------|
+| **GET** | `/api/v1/user` | [Get the authenticated user](/products/hosted/api/v1/user#getCurrentUser) |
+
+### Deployment
+
+| Method | Path | What it does |
+|--------|------|--------------|
+| **GET** | `/api/v1/deployment-options` | [List the options a deployment can be created with](/products/hosted/api/v1/deployment#getDeploymentOptions) |
+| **POST** | `/api/v1/deployments` | [Create a deployment](/products/hosted/api/v1/deployment#createDeployment) |
+| **GET** | `/api/v1/deployments/{owner}` | [List an owner's deployments](/products/hosted/api/v1/deployment#listDeployments) |
+| **GET** | `/api/v1/deployments/{owner}/{deployment}` | [Get a deployment](/products/hosted/api/v1/deployment#getDeployment) |
+| **GET** | `/api/v1/deployments/{owner}/{deployment}/instances` | [List a deployment's instances](/products/hosted/api/v1/deployment#listDeploymentInstances) |
+
+## Response shape
+
+Every `2xx` response body is an [Envelope](/products/hosted/api/v1/models#model-envelope): the resource, or an array of resources, under `data`, with optional `meta`.
+
+```json
+{
+ "data": { "owner": "acme", "name": "analytics", "state": "started" }
+}
+```
+
+List endpoints put the pagination cursor in `meta`:
+
+```json
+{
+ "data": [ { "owner": "acme", "name": "analytics" } ],
+ "meta": { "next_page_token": "eyJvZmZzZXQiOjI1fQ" }
+}
+```
+
+When `meta.next_page_token` is present, pass it back as the `page_token` query parameter to fetch the next page. On the last page `meta` is omitted entirely, so checking whether the token is present is all a client needs — it is never returned present but empty.
+
+## Errors
+
+Every non-`2xx` response is a [Problem](/products/hosted/api/v1/models#model-problem) with content type `application/problem+json`:
+
+```json
+{
+ "type": "https://docs.dolthub.com/products/hosted/api/v1/models/#model-errorcode",
+ "title": "Not found",
+ "status": 404,
+ "detail": "Deployment 'analytics' does not exist for owner 'acme'",
+ "instance": "/api/v1/deployments/acme/analytics",
+ "code": "NOT_FOUND",
+ "request_id": "req_01HZX9P7Q5N2M8"
+}
+```
+
+Branch on `code` — a stable, machine-readable [ErrorCode](/products/hosted/api/v1/models#model-errorcode) — never on the human-readable `title` or `detail`, which may be reworded at any time.
+
+Every response, including successful ones, carries an `x-request-id` header, echoed in the body as `request_id` on errors. Include it when contacting support so a request can be traced end to end.
+
+## Long-running work
+
+Creating a deployment returns `202 Accepted` with the deployment in its `starting` state — provisioning continues after the response. Poll [Get a deployment](/products/hosted/api/v1/deployment#getDeployment) until `state` becomes `started`.
+
+Deployment names are unique within an owner, which makes creates idempotent by name: retrying after an ambiguous failure returns `409 Conflict` rather than provisioning a second deployment.
+
+> **Creating a deployment incurs cost.**
+
+## Stability
+
+v1 is additive. New endpoints, new optional request fields, new response fields, and new `ErrorCode` values may be introduced within v1. Renaming or removing a field, or changing an existing one's meaning, requires a new major version.
diff --git a/site/dolt/src/content/products/hosted/api/v1/authentication.md b/site/dolt/src/content/products/hosted/api/v1/authentication.md
new file mode 100644
index 00000000..f2650cd1
--- /dev/null
+++ b/site/dolt/src/content/products/hosted/api/v1/authentication.md
@@ -0,0 +1,59 @@
+---
+title: "Authentication"
+description: How to authenticate requests to the Hosted Dolt v1 API.
+---
+
+# Authentication
+
+_API version: v1_
+
+Every v1 endpoint requires authentication. The only credential type is a **Hosted API token**, sent in the `Authorization` header as a bearer token.
+
+## Creating a token
+
+Create a token from the **Tokens** section of your account settings at [hosted.doltdb.com/settings/tokens](https://hosted.doltdb.com/settings/tokens). Give it a name that says where it will be used — `deploy pipeline`, `staging bootstrap` — since that name is how you will identify it later.
+
+Copy the token immediately. Only a hash of it is stored, so the secret is shown once and cannot be recovered afterwards. If you lose it, delete the token and create another.
+
+Tokens are prefixed `hsat.v1.`.
+
+## Using a token
+
+Send it as a bearer token on every request:
+
+```sh
+curl 'https://hosted.doltdb.com/api/v1/user' \
+ -H 'Authorization: Bearer hsat.v1.YOUR_TOKEN_HERE'
+```
+
+`GET /api/v1/user` is the cheapest way to check a credential: a `200` confirms the token is valid and shows whose access it carries.
+
+In a script, keep the token in an environment variable rather than in the source:
+
+```sh
+export HOSTED_API_TOKEN='hsat.v1.YOUR_TOKEN_HERE'
+
+curl 'https://hosted.doltdb.com/api/v1/deployments/acme' \
+ -H "Authorization: Bearer $HOSTED_API_TOKEN"
+```
+
+## Permissions
+
+A token carries the full permissions of the user who created it. There are no per-token scopes in v1 — anything you can do in the web UI, a token of yours can do through the API, including [creating deployments, which incurs cost](/products/hosted/api/v1/deployment#createDeployment).
+
+Access to a particular deployment still follows that deployment's own roles. A deployment you cannot see returns `404` rather than `403`, so the API never reveals that a deployment exists to someone without access to it.
+
+## Expiry and revocation
+
+Every token has an expiry date, chosen when you create it — 30, 60, or 90 days, or one year. There is deliberately no non-expiring option; rotate long-lived automation on a schedule that matches the expiry you pick.
+
+Delete a token from the same settings page to revoke it immediately. The tokens table also shows when each token was last used, and from where, which is the fastest way to find out whether a token is still in service before you delete it.
+
+## Failure responses
+
+| Status | Code | Meaning |
+|--------|------|---------|
+| `401` | `UNAUTHENTICATED` | The `Authorization` header was missing, malformed, or the token is invalid or expired. |
+| `403` | `PERMISSION_DENIED` | The token is valid, but its user is not permitted to perform this action. |
+
+Both are returned as [Problem](/products/hosted/api/v1/models#model-problem) documents. See the [v1 overview](/products/hosted/api/v1#errors) for the error model.
diff --git a/site/dolt/src/content/products/hosted/api/v1/deployment.md b/site/dolt/src/content/products/hosted/api/v1/deployment.md
new file mode 100644
index 00000000..b6b5a32f
--- /dev/null
+++ b/site/dolt/src/content/products/hosted/api/v1/deployment.md
@@ -0,0 +1,362 @@
+---
+title: "Deployment"
+description: Creating, listing, and reading Hosted Dolt deployments and their instances.
+---
+
+# Deployment
+
+Hosted Dolt deployments and their lifecycle.
+
+## List the options a deployment can be created with {#getDeploymentOptions}
+GET /api/v1/deployment-options
+
+Returns the zones, instance types, and storage options available for a cloud, so a caller can construct a valid `POST /api/v1/deployments` request.
+
+The options narrow in steps, because each depends on the one before it. Supply `cloud` alone for its zones; add `zone` to also get that zone's instance types; add `instance_type_id` to also get the storage options compatible with that instance. Fields you haven't narrowed enough to determine are absent rather than empty.
+
+Each list is filtered to what you selected: supplying `zone` narrows `zones` to that zone, and supplying `instance_type_id` narrows `instance_types` to that instance type. A fully narrowed request therefore describes one combination rather than repeating the whole catalogue.
+
+A `zone` or `instance_type_id` that doesn't exist is a `422` rather than an empty result, so a typo can't be mistaken for a combination with nothing available. `instance_type_id` requires `zone`; supplying it alone is a `400`.
+
+The `id` of an instance type or storage option is what `POST /api/v1/deployments` accepts; `name` is for display.
+
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+|------|----|------|----------|-------------|
+| `cloud` | query | string | yes | The cloud to list options for. |
+| `zone` | query | string | no | A zone from this cloud's `zones`. Supply it to receive `instance_types`. |
+| `instance_type_id` | query | string | no | An instance type `id` from `instance_types`. Supply it, together with `zone`, to receive `storage_options`. |
+
+**Example request**
+
+```sh
+curl -X GET 'https://hosted.doltdb.com/api/v1/deployment-options?cloud=aws' \
+ -H 'Authorization: Bearer YOUR_TOKEN'
+```
+
+**Responses**
+
+| Status | Description | Schema |
+|--------|-------------|--------|
+| `200` | The available options, narrowed by the supplied parameters. | [`DeploymentOptions`](/products/hosted/api/v1/models#model-deploymentoptions) |
+| `400` | The request was malformed or failed input validation. | |
+| `401` | Authentication credentials were missing or invalid. | |
+| `405` | The HTTP method is not supported for this resource. | |
+| `422` | The request was well-formed but semantically invalid. | |
+| `500` | An unexpected server error occurred. | |
+| `503` | The service is temporarily unavailable. | |
+
+**Example response `200`**
+
+```json
+{
+ "data": {
+ "cloud": "aws",
+ "zones": [
+ "us-east-1"
+ ],
+ "instance_types": [
+ {
+ "id": "aws.t2.medium",
+ "name": "t2.medium",
+ "cpus": 2,
+ "memory_gb": 4,
+ "description": "Trial tier, the lowest spec that runs a Dolt SQL server.",
+ "hourly_cost_usd": 0.06849315
+ }
+ ],
+ "storage_options": [
+ {
+ "id": "aws.ebs.gp3_50",
+ "name": "Trial 50GB EBS",
+ "description": "Trial tier storage capped at 50GB",
+ "min_size_gb": 50,
+ "max_size_gb": 50,
+ "monthly_cost_usd_per_gb": 0
+ }
+ ]
+ }
+}
+```
+
+---
+
+## Create a deployment {#createDeployment}
+POST /api/v1/deployments
+
+Provisions a new deployment and returns `202` with the deployment in its `starting` state. Provisioning continues after the response: poll `GET /api/v1/deployments/{owner}/{deployment}` until `state` becomes `started`.
+
+Deployment names are unique within an owner, so a create is idempotent by name — a retry after an ambiguous failure returns `409` rather than provisioning a second deployment. Callers should still treat `409` as "it already exists", not as a different failure.
+
+`instance_type_id` and `volume_type_id` take the **ids** from the deployment options endpoint, not the display names a deployment reports back on a read.
+
+As with any create, a `5xx` or a dropped connection does not tell you whether the deployment was created — the call can succeed remotely and fail on the way back. Retry: it returns `409` if the deployment now exists, and `GET` confirms either way.
+
+**Creating a deployment incurs cost.**
+
+
+**Request body**
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `owner` | string | yes | The user or organization that will own the deployment. The caller must have permission to create deployments for it. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `name` | string | yes | The deployment name, unique within the owner. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `cloud` | string | yes | The cloud the deployment runs in. |
+| `zone` | string | yes | The cloud region to provision in, as listed by the deployment options. |
+| `cluster_type` | string | no | The database engine the deployment runs. `mysql_with_dolt_replicas` is a MySQL primary with Dolt read replicas. |
+| `instance_type_id` | string | yes | The **id** of the instance type, from the deployment options endpoint. Note a deployment reports `instance_type_name` on a read — the id and the display name are different values. |
+| `volume_type_id` | string | yes | The **id** of the storage type, from the deployment options endpoint. As with `instance_type_id`, this is the id rather than the display name. |
+| `volume_size_gb` | integer | yes | The size of the storage volume, in gigabytes. Must fall within the selected storage type's supported range. |
+| `replicas` | integer | no | The number of read replicas. Defaults to `0` when omitted. |
+| `webpki_cert` | boolean | no | Serve a publicly-trusted (WebPKI) TLS certificate rather than a Hosted-issued one. Defaults to `false` when omitted. |
+| `expose_remotesapi_endpoint` | boolean | no | Expose a Dolt remotes API endpoint. Defaults to `false` when omitted. |
+| `expose_mcp` | boolean | no | Expose an MCP endpoint. Defaults to `false` when omitted. |
+| `expose_stats` | boolean | no | Expose a statistics endpoint. Defaults to `false` when omitted. |
+
+**Example request**
+
+```sh
+curl -X POST 'https://hosted.doltdb.com/api/v1/deployments' \
+ -H 'Authorization: Bearer YOUR_TOKEN' \
+ -H 'Content-Type: application/json' \
+ -d '{"owner":"acme","name":"analytics","cloud":"aws","zone":"us-east-1","instance_type_id":"aws.t2.medium","volume_type_id":"aws.ebs.gp3_50","volume_size_gb":50}'
+```
+
+**Responses**
+
+| Status | Description | Schema |
+|--------|-------------|--------|
+| `202` | The deployment has been accepted and is provisioning. `state` is `starting`. | [`Deployment`](/products/hosted/api/v1/models#model-deployment) |
+| `400` | The request was malformed or failed input validation. | |
+| `401` | Authentication credentials were missing or invalid. | |
+| `403` | Authenticated, but not permitted to perform this action. | |
+| `405` | The HTTP method is not supported for this resource. | |
+| `409` | The request conflicts with the current state of the resource (e.g. it already exists). | |
+| `422` | The request was well-formed but semantically invalid. | |
+| `500` | An unexpected server error occurred. | |
+| `503` | The service is temporarily unavailable. | |
+
+**Example response `202`**
+
+```json
+{
+ "data": {
+ "owner": "acme",
+ "name": "analytics",
+ "state": "starting",
+ "cloud": "aws",
+ "zone": "us-east-1",
+ "cluster_type": "dolt",
+ "instance_type_name": "t2.medium",
+ "volume_type_name": "Trial 50GB EBS",
+ "volume_size_gb": 50,
+ "replicas": 0,
+ "host": "",
+ "port": 3306,
+ "caller_role": "admin",
+ "created_by": "acme-ops",
+ "created_at": "2026-08-11T09:14:00Z"
+ }
+}
+```
+
+---
+
+## List an owner's deployments {#listDeployments}
+GET /api/v1/deployments/{owner}
+
+Returns the deployments belonging to `{owner}` that the caller can see, newest cursor page first. Requires a credential with access to the owner.
+
+Items are `DeploymentSummary`, not the full `Deployment` — the backing RPC returns a narrower shape for lists. Fetch `GET /api/v1/deployments/{owner}/{deployment}` for the complete resource.
+
+Pagination is cursor-based: when `meta.next_page_token` is present, pass it back as `page_token` to fetch the next page. On the last page `meta` is omitted entirely, so presence of the token is the only check a client needs.
+
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+|------|----|------|----------|-------------|
+| `owner` | path | string | yes | The user or organization whose deployments to list. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `page_token` | query | string | no | The `meta.next_page_token` from a previous response. Omit for the first page. |
+| `state` | query | string | no | Return only deployments in this state. Omit for all states. |
+
+**Example request**
+
+```sh
+curl -X GET 'https://hosted.doltdb.com/api/v1/deployments/{owner}' \
+ -H 'Authorization: Bearer YOUR_TOKEN'
+```
+
+**Responses**
+
+| Status | Description | Schema |
+|--------|-------------|--------|
+| `200` | The owner's deployments. | [`DeploymentSummary[]`](/products/hosted/api/v1/models#model-deploymentsummary) |
+| `400` | The request was malformed or failed input validation. | |
+| `401` | Authentication credentials were missing or invalid. | |
+| `403` | Authenticated, but not permitted to perform this action. | |
+| `404` | The requested resource does not exist. | |
+| `405` | The HTTP method is not supported for this resource. | |
+| `500` | An unexpected server error occurred. | |
+
+**Example response `200`**
+
+```json
+{
+ "data": [
+ {
+ "owner": "acme",
+ "name": "analytics",
+ "state": "started",
+ "cloud": "aws",
+ "zone": "us-west-2",
+ "cluster_type": "dolt",
+ "instance_type_name": "m5.large",
+ "volume_type_name": "gp3",
+ "volume_size_gb": 100,
+ "replicas": 0,
+ "database_version": "1.58.4",
+ "hourly_cost_usd": 0.192,
+ "webpki_cert": true
+ }
+ ],
+ "meta": {
+ "next_page_token": "eyJvZmZzZXQiOjI1fQ"
+ }
+}
+```
+
+---
+
+## Get a deployment {#getDeployment}
+GET /api/v1/deployments/{owner}/{deployment}
+
+Returns the deployment `{owner}/{deployment}`. Requires a credential with at least read access; a deployment the caller cannot see returns `404` rather than `403`, so its existence isn't leaked.
+
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+|------|----|------|----------|-------------|
+| `owner` | path | string | yes | The user or organization that owns the deployment. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `deployment` | path | string | yes | The deployment name, unique within the owner. 3–32 characters of letters, digits, hyphens, and underscores. |
+
+**Example request**
+
+```sh
+curl -X GET 'https://hosted.doltdb.com/api/v1/deployments/{owner}/{deployment}' \
+ -H 'Authorization: Bearer YOUR_TOKEN'
+```
+
+**Responses**
+
+| Status | Description | Schema |
+|--------|-------------|--------|
+| `200` | The deployment. | [`Deployment`](/products/hosted/api/v1/models#model-deployment) |
+| `400` | The request was malformed or failed input validation. | |
+| `401` | Authentication credentials were missing or invalid. | |
+| `404` | The requested resource does not exist. | |
+| `405` | The HTTP method is not supported for this resource. | |
+| `500` | An unexpected server error occurred. | |
+| `503` | The service is temporarily unavailable. | |
+
+**Example response `200`**
+
+```json
+{
+ "data": {
+ "owner": "acme",
+ "name": "analytics",
+ "state": "started",
+ "cloud": "aws",
+ "zone": "us-east-1",
+ "cluster_type": "dolt",
+ "instance_type_name": "t2.medium",
+ "volume_type_name": "Trial 50GB EBS",
+ "volume_size_gb": 50,
+ "replicas": 0,
+ "database_version": "1.58.4",
+ "host": "analytics.dbs.hosted.doltdb.com",
+ "port": 3306,
+ "hourly_cost_usd": 0.06849315,
+ "webpki_cert": true,
+ "expose_remotesapi_endpoint": false,
+ "expose_mcp": false,
+ "expose_stats": false,
+ "disable_automatic_dolt_updates": false,
+ "caller_role": "admin",
+ "created_by": "acme-ops",
+ "created_at": "2026-07-01T18:22:04Z"
+ }
+}
+```
+
+---
+
+## List a deployment's instances {#listDeploymentInstances}
+GET /api/v1/deployments/{owner}/{deployment}/instances
+
+Returns the instances backing `{owner}/{deployment}` — one for a single-instance deployment, or a primary plus its read replicas.
+
+Stopped instances are not listed; starting, started, and stopping ones all are. So an instance appearing here is part of the deployment but not necessarily serving traffic, and an empty array means it has none outside the stopped state — normal while a deployment is itself `starting`.
+
+The list is not paginated: a deployment has a primary and its replicas, a set small enough to return whole.
+
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+|------|----|------|----------|-------------|
+| `owner` | path | string | yes | The user or organization that owns the deployment. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `deployment` | path | string | yes | The deployment name, unique within the owner. 3–32 characters of letters, digits, hyphens, and underscores. |
+
+**Example request**
+
+```sh
+curl -X GET 'https://hosted.doltdb.com/api/v1/deployments/{owner}/{deployment}/instances' \
+ -H 'Authorization: Bearer YOUR_TOKEN'
+```
+
+**Responses**
+
+| Status | Description | Schema |
+|--------|-------------|--------|
+| `200` | The deployment's non-stopped instances. | [`DeploymentInstance[]`](/products/hosted/api/v1/models#model-deploymentinstance) |
+| `400` | The request was malformed or failed input validation. | |
+| `401` | Authentication credentials were missing or invalid. | |
+| `404` | The requested resource does not exist. | |
+| `405` | The HTTP method is not supported for this resource. | |
+| `500` | An unexpected server error occurred. | |
+| `503` | The service is temporarily unavailable. | |
+
+**Example response `200`**
+
+```json
+{
+ "data": [
+ {
+ "id": "9b1f5c2e-4d3a-4f8b-9c0d-1e2f3a4b5c6d",
+ "index": 0,
+ "is_primary": true,
+ "host": "analytics-0.dbs.hosted.doltdb.com",
+ "instance_type_name": "t2.medium",
+ "volume_type_name": "Trial 50GB EBS",
+ "volume_size_gb": 50,
+ "hourly_cost_usd": 0.06849315
+ },
+ {
+ "id": "2c4e6a8b-1d3f-4a5c-8e9b-0f1a2b3c4d5e",
+ "index": 1,
+ "is_primary": false,
+ "host": "analytics-1.dbs.hosted.doltdb.com",
+ "instance_type_name": "t2.medium",
+ "volume_type_name": "Trial 50GB EBS",
+ "volume_size_gb": 50,
+ "hourly_cost_usd": 0.06849315
+ }
+ ]
+}
+```
+
diff --git a/site/dolt/src/content/products/hosted/api/v1/models.md b/site/dolt/src/content/products/hosted/api/v1/models.md
new file mode 100644
index 00000000..8a498e2d
--- /dev/null
+++ b/site/dolt/src/content/products/hosted/api/v1/models.md
@@ -0,0 +1,279 @@
+---
+title: "Models"
+description: Request and response schemas for the Hosted v1 API.
+---
+
+# Models
+
+Shared request and response types used across the v1 API. See the [error model](#model-problem) for how failures are reported.
+
+## ErrorCode {#model-errorcode}
+A stable, machine-readable error code in SCREAMING_SNAKE_CASE. Clients branch on this value, never on the human-readable `title`/`detail` prose. The baseline codes below cover the standard HTTP failure categories; endpoint-specific codes (e.g. `DEPLOYMENT_NOT_FOUND`) are appended to this enum alongside the endpoints that emit them, which is an additive, non-breaking change under the v1 stability policy.
+
+**Enum values**
+
+| Value |
+|-------|
+| `VALIDATION_FAILED` |
+| `UNAUTHENTICATED` |
+| `PERMISSION_DENIED` |
+| `NOT_FOUND` |
+| `METHOD_NOT_ALLOWED` |
+| `CONFLICT` |
+| `UNPROCESSABLE` |
+| `RATE_LIMITED` |
+| `INTERNAL` |
+| `SERVICE_UNAVAILABLE` |
+| `OPERATION_FAILED` |
+
+---
+
+## Problem {#model-problem}
+A structured error body returned for every non-2xx response, following RFC 9457 (Problem Details for HTTP APIs). This is the single error model for the entire v1 API — there are no ad-hoc error shapes.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `type` | `string` | yes | A URI identifying the problem type; when dereferenced it points at human-readable documentation for the error. |
+| `title` | `string` | yes | A short, human-readable summary of the problem type. |
+| `status` | `integer` | yes | The HTTP status code, repeated in the body for convenience. |
+| `detail` | `string` | no | A human-readable explanation specific to this occurrence of the problem. |
+| `instance` | `string` | no | A URI reference identifying the specific occurrence (typically the request path). |
+| `code` | `string` | yes | A stable, machine-readable error code in SCREAMING_SNAKE_CASE. Clients branch on this value, never on the human-readable `title`/`detail` prose. The baseline codes below cover the standard HTTP failure categories; endpoint-specific codes (e.g. `DEPLOYMENT_NOT_FOUND`) are appended to this enum alongside the endpoints that emit them, which is an additive, non-breaking change under the v1 stability policy. |
+| `request_id` | `string` | yes | The request identifier, echoed on every response. Include it when contacting support so a request can be traced end-to-end. |
+
+---
+
+## Meta {#model-meta}
+Response metadata carried alongside the primary `data` payload. All fields are optional; list endpoints populate `next_page_token` for cursor pagination.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `next_page_token` | `string` | no | Opaque cursor for the next page of a list response. Absent when there are no further results — never present and empty — otherwise pass it back as the `page_token` query parameter to fetch the next page. |
+
+---
+
+## Envelope {#model-envelope}
+The success envelope wrapping every 2xx response body: the resource or list of resources under `data`, with optional `meta`. This is the single success shape for the API — there are no unenveloped success bodies. Endpoints narrow `data` to a concrete resource via `allOf`; the base leaves `data` unconstrained so that composition works.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `data` | `object,array` | yes | The primary response payload — a resource, or an array of resources for list endpoints. |
+| `meta` | `object` | no | Response metadata carried alongside the primary `data` payload. All fields are optional; list endpoints populate `next_page_token` for cursor pagination. |
+
+---
+
+## UserEmailAddress {#model-useremailaddress}
+An email address belonging to a user.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `address` | `string` | yes | The email address. |
+| `is_verified` | `boolean` | yes | Whether the address has completed email verification. |
+| `is_primary` | `boolean` | yes | Whether this is the user's primary address. Exactly one address is primary. |
+
+---
+
+## User {#model-user}
+A Hosted user. `GET /api/v1/user` returns the authenticated user's profile. v1 returns only public-facing profile fields — the identity provider the account signs in with, session state, and credential metadata are never included.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `username` | `string` | yes | The user's Hosted username (unique handle). |
+| `display_name` | `string` | no | The user's display name. May be empty. |
+| `company` | `string` | no | The user's stated company. May be empty. |
+| `email_addresses` | `array` | yes | The user's email addresses. Returned only for the authenticated user themselves; empty for any other caller. |
+
+---
+
+## InstanceType {#model-instancetype}
+A compute instance type a deployment can run on.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `id` | `string` | yes | The identifier `POST /api/v1/deployments` accepts as `instance_type_id`. |
+| `name` | `string` | yes | The display name. A deployment reports this as `instance_type_name`. |
+| `cpus` | `integer` | no | Virtual CPUs. |
+| `memory_gb` | `integer` | no | Memory, in gigabytes. |
+| `description` | `string` | no | A human-readable summary of what the instance suits. |
+| `hourly_cost_usd` | `number` | no | Cost per hour in US dollars. Absent when no hourly price is published for this instance type. |
+
+---
+
+## StorageOption {#model-storageoption}
+A storage type a deployment's volume can use.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `id` | `string` | yes | The identifier `POST /api/v1/deployments` accepts as `volume_type_id`. |
+| `name` | `string` | yes | The display name. A deployment reports this as `volume_type_name`. |
+| `description` | `string` | no | A human-readable summary of the storage type. |
+| `min_size_gb` | `integer` | no | Smallest volume size this type supports, in gigabytes. `volume_size_gb` on a create request must be at least this. |
+| `max_size_gb` | `integer` | no | Largest volume size this type supports, in gigabytes. |
+| `monthly_cost_usd_per_gb` | `number` | no | Cost per gigabyte per month, in US dollars. |
+
+---
+
+## DeploymentInstance {#model-deploymentinstance}
+One instance backing a deployment. A deployment has a primary and, when it has read replicas, one instance per replica.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `id` | `string` | yes | The instance's identifier, unique within the deployment. |
+| `index` | `integer` | yes | The instance's position in the deployment. `0` is the first instance; replicas take the following indices. |
+| `is_primary` | `boolean` | yes | Whether this instance is currently the primary. Exactly one instance of a started deployment is primary, and which one can change over the deployment's life. |
+| `host` | `string` | no | The hostname for this specific instance. Connect to the deployment's own `host` unless you mean to address one instance directly. |
+| `instance_type_name` | `string` | no | The display name of this instance's type. |
+| `volume_type_name` | `string` | no | The display name of this instance's storage type. |
+| `volume_size_gb` | `integer` | no | The size of this instance's storage volume, in gigabytes. |
+| `hourly_cost_usd` | `number` | no | This instance's cost per hour, in US dollars. A deployment's total is the sum across its instances. |
+
+---
+
+## DeploymentOptions {#model-deploymentoptions}
+The options available for creating a deployment, narrowed by the query parameters supplied. `instance_types` and `storage_options` are absent until enough of the chain has been supplied to determine them.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `cloud` | `string` | yes | The cloud the deployment runs in. |
+| `zones` | `array` | yes | The zones this cloud supports. |
+| `instance_types` | `array` | no | Instance types available in the requested `zone`. Absent when `zone` wasn't supplied. |
+| `storage_options` | `array` | no | Storage types compatible with the requested `instance_type_id`. Absent when `zone` and `instance_type_id` weren't both supplied. |
+
+---
+
+## CreateDeploymentRequest {#model-createdeploymentrequest}
+The provisioning parameters for a new deployment.
+
+v1.0 exposes the core parameters only. Restoring from a backup, cloning an existing deployment, workbench user settings, and private networking are all settable on the internal API but are not part of this request; each is its own feature with its own contract, and adding them is additive. The internal deployment test flag is deliberately not exposed at all.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `owner` | `string` | yes | The user or organization that will own the deployment. The caller must have permission to create deployments for it. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `name` | `string` | yes | The deployment name, unique within the owner. 3–32 characters of letters, digits, hyphens, and underscores. |
+| `cloud` | `string` | yes | The cloud the deployment runs in. |
+| `zone` | `string` | yes | The cloud region to provision in, as listed by the deployment options. |
+| `cluster_type` | `string` | no | The database engine the deployment runs. `mysql_with_dolt_replicas` is a MySQL primary with Dolt read replicas. |
+| `instance_type_id` | `string` | yes | The **id** of the instance type, from the deployment options endpoint. Note a deployment reports `instance_type_name` on a read — the id and the display name are different values. |
+| `volume_type_id` | `string` | yes | The **id** of the storage type, from the deployment options endpoint. As with `instance_type_id`, this is the id rather than the display name. |
+| `volume_size_gb` | `integer` | yes | The size of the storage volume, in gigabytes. Must fall within the selected storage type's supported range. |
+| `replicas` | `integer` | no | The number of read replicas. Defaults to `0` when omitted. |
+| `webpki_cert` | `boolean` | no | Serve a publicly-trusted (WebPKI) TLS certificate rather than a Hosted-issued one. Defaults to `false` when omitted. |
+| `expose_remotesapi_endpoint` | `boolean` | no | Expose a Dolt remotes API endpoint. Defaults to `false` when omitted. |
+| `expose_mcp` | `boolean` | no | Expose an MCP endpoint. Defaults to `false` when omitted. |
+| `expose_stats` | `boolean` | no | Expose a statistics endpoint. Defaults to `false` when omitted. |
+
+---
+
+## DeploymentState {#model-deploymentstate}
+The deployment's lifecycle state. `starting` covers both initial provisioning and a restart; poll this field to observe a create or a resize reaching `started`.
+
+**Enum values**
+
+| Value |
+|-------|
+| `starting` |
+| `started` |
+| `stopping` |
+| `stopped` |
+
+---
+
+## CloudProvider {#model-cloudprovider}
+The cloud the deployment runs in.
+
+**Enum values**
+
+| Value |
+|-------|
+| `aws` |
+| `gcp` |
+| `azure` |
+
+---
+
+## ClusterType {#model-clustertype}
+The database engine the deployment runs. `mysql_with_dolt_replicas` is a MySQL primary with Dolt read replicas.
+
+**Enum values**
+
+| Value |
+|-------|
+| `dolt` |
+| `doltgres` |
+| `mysql_with_dolt_replicas` |
+
+---
+
+## DeploymentRole {#model-deploymentrole}
+The authenticated caller's role on this deployment. Always present on a read, since a caller without at least read access cannot retrieve the deployment at all.
+
+**Enum values**
+
+| Value |
+|-------|
+| `admin` |
+| `writer` |
+| `reader` |
+| `reader_and_pulls` |
+
+---
+
+## DeploymentSummary {#model-deploymentsummary}
+A deployment as it appears in a list.
+
+This is deliberately not the same shape as `Deployment`. The list RPC returns a narrower record — it omits connection details, the caller's role, and the creation audit fields, and it adds the last-backup figures shown in fleet views. Read the deployment itself for the full resource. As with `Deployment`, database credentials are never included.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `owner` | `string` | yes | The user or organization that owns the deployment. |
+| `name` | `string` | yes | The deployment name, unique within the owner. |
+| `state` | `string` | yes | The deployment's lifecycle state. `starting` covers both initial provisioning and a restart; poll this field to observe a create or a resize reaching `started`. |
+| `cloud` | `string` | yes | The cloud the deployment runs in. |
+| `zone` | `string` | yes | The cloud region the deployment runs in. |
+| `cluster_type` | `string` | yes | The database engine the deployment runs. `mysql_with_dolt_replicas` is a MySQL primary with Dolt read replicas. |
+| `instance_type_name` | `string` | no | The display name of the deployment's instance type. |
+| `volume_type_name` | `string` | no | The display name of the deployment's storage type. |
+| `volume_size_gb` | `integer` | no | The size of the deployment's storage volume, in gigabytes. |
+| `replicas` | `integer` | no | The number of read replicas. `0` for a single-instance deployment. |
+| `database_version` | `string` | no | The version of the database engine the deployment is running — a Dolt version for a `dolt` cluster, a Doltgres version for a `doltgres` one. |
+| `hourly_cost_usd` | `number` | no | The deployment's current cost per hour, in US dollars. |
+| `webpki_cert` | `boolean` | no | Whether the deployment serves a publicly-trusted (WebPKI) TLS certificate. |
+| `last_backup_size_bytes` | `integer` | no | Size of the most recent backup, in bytes. Absent when no backup has been taken or its size has not been computed yet. |
+| `last_backup_time` | `string` | no | When the most recent backup was taken. Absent when no backup has been taken. |
+
+---
+
+## Deployment {#model-deployment}
+A Hosted Dolt deployment.
+
+v1 returns configuration and lifecycle state only. The deployment's database credentials are deliberately **not** part of this resource — they are issued and rotated through the deployment credentials endpoints, so that reading a deployment is never a credential-disclosing operation.
+
+Provider-specific private-networking configuration (AWS PrivateLink, GCP Private Service Connect, Azure Private Link) is not included in v1.0. Each carries its own endpoint collection and provisioning state, and will land as its own sub-resource; adding it is additive under the stability policy.
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `owner` | `string` | yes | The user or organization that owns the deployment. |
+| `name` | `string` | yes | The deployment name, unique within the owner. |
+| `state` | `string` | yes | The deployment's lifecycle state. `starting` covers both initial provisioning and a restart; poll this field to observe a create or a resize reaching `started`. |
+| `cloud` | `string` | yes | The cloud the deployment runs in. |
+| `zone` | `string` | yes | The cloud region the deployment runs in. |
+| `cluster_type` | `string` | yes | The database engine the deployment runs. `mysql_with_dolt_replicas` is a MySQL primary with Dolt read replicas. |
+| `instance_type_name` | `string` | no | The display name of the deployment's instance type. Note this is the *name*, not the id that `POST /api/v1/deployments` accepts; both are listed by the deployment options endpoint. |
+| `volume_type_name` | `string` | no | The display name of the deployment's storage type. As with `instance_type_name`, this is the name rather than the id used to create a deployment. |
+| `volume_size_gb` | `integer` | no | The size of the deployment's storage volume, in gigabytes. |
+| `replicas` | `integer` | no | The number of read replicas. `0` for a single-instance deployment. |
+| `database_version` | `string` | no | The version of the database engine the deployment is running — a Dolt version for a `dolt` cluster, a Doltgres version for a `doltgres` one. |
+| `host` | `string` | no | The hostname clients connect to. Empty until the deployment reaches `started`. |
+| `port` | `integer` | no | The port clients connect to. |
+| `hourly_cost_usd` | `number` | no | The deployment's current cost per hour, in US dollars. |
+| `webpki_cert` | `boolean` | no | Whether the deployment serves a publicly-trusted (WebPKI) TLS certificate rather than a Hosted-issued one. |
+| `expose_remotesapi_endpoint` | `boolean` | no | Whether the deployment exposes a Dolt remotes API endpoint. |
+| `expose_mcp` | `boolean` | no | Whether the deployment exposes an MCP endpoint. |
+| `expose_stats` | `boolean` | no | Whether the deployment exposes a statistics endpoint. |
+| `disable_automatic_dolt_updates` | `boolean` | no | Whether automatic Dolt version updates are disabled for this deployment. |
+| `caller_role` | `string` | yes | The authenticated caller's role on this deployment. Always present on a read, since a caller without at least read access cannot retrieve the deployment at all. |
+| `created_by` | `string` | no | The username of the user who created the deployment. |
+| `created_at` | `string` | yes | When the deployment was created. |
+| `destroy_at` | `string` | no | When the deployment is scheduled to be destroyed. Absent unless a destroy has been scheduled. |
+| `destroyed_by` | `string` | no | The username of the user who destroyed the deployment. Absent unless it has been destroyed. |
+
diff --git a/site/dolt/src/content/products/hosted/api/v1/user.md b/site/dolt/src/content/products/hosted/api/v1/user.md
new file mode 100644
index 00000000..916cfe58
--- /dev/null
+++ b/site/dolt/src/content/products/hosted/api/v1/user.md
@@ -0,0 +1,50 @@
+---
+title: "User"
+description: The authenticated user resource in the Hosted v1 API.
+---
+
+# User
+
+The authenticated user.
+
+## Get the authenticated user {#getCurrentUser}
+GET /api/v1/user
+
+Returns the profile of the user identified by the request's credentials. Useful as a credential check: a `200` confirms the token is valid and shows whose access it carries.
+
+
+**Example request**
+
+```sh
+curl -X GET 'https://hosted.doltdb.com/api/v1/user' \
+ -H 'Authorization: Bearer YOUR_TOKEN'
+```
+
+**Responses**
+
+| Status | Description | Schema |
+|--------|-------------|--------|
+| `200` | The authenticated user's profile. | [`User`](/products/hosted/api/v1/models#model-user) |
+| `401` | Authentication credentials were missing or invalid. | |
+| `405` | The HTTP method is not supported for this resource. | |
+| `500` | An unexpected server error occurred. | |
+
+**Example response `200`**
+
+```json
+{
+ "data": {
+ "username": "acme-ops",
+ "display_name": "Acme Operations",
+ "company": "Acme Corp",
+ "email_addresses": [
+ {
+ "address": "ops@acme.com",
+ "is_verified": true,
+ "is_primary": true
+ }
+ ]
+ }
+}
+```
+
diff --git a/site/dolt/src/content/products/hosted/cloning.md b/site/dolt/src/content/products/hosted/cloning.md
index 606e752a..4ad63ed5 100644
--- a/site/dolt/src/content/products/hosted/cloning.md
+++ b/site/dolt/src/content/products/hosted/cloning.md
@@ -33,7 +33,7 @@ analytics query. [Clone](/cli-reference/cli#dolt-clone) makes it easy to get a l
copy of your Hosted database with one command. Do whatever potentially destructive or
performance-degrading operations on your laptop while respecting your production database.
-## 1. Expose remotesapi endpoint
+### 1. Expose remotesapi endpoint
In order to enable cloning from your Hosted database, first expose the [remotesapi
endpoint](/cli-reference/cli#dolt-sql-server). This will set the port for a server
@@ -48,7 +48,7 @@ deployment will also work.

-## 2. Set remote password and run clone command with user flag
+### 2. Set remote password and run clone command with user flag
To authenticate against it, you have to set a `DOLT_REMOTE_PASSWORD` environment variable
and pass along a `--user` flag to the `dolt clone` command. You can find these
@@ -92,7 +92,7 @@ cloning https://dolthub-us-housing.dbs.hosted.doltdb.com/us-housing-prices
+----------+
```
-## 3. Sync your local copy with upstream changes
+### 3. Sync your local copy with upstream changes
Now we can run whatever queries or schema migrations we want without affecting production.
If there are updates to the database, easily sync your local copy using [`dolt
@@ -107,7 +107,7 @@ commands to your remotesapi endpoint in the same way by passing the `--user` fla
% dolt fetch --user "[username]"
```
-## 4. Sync your upstream with changes from local copy
+### 4. Sync your upstream with changes from local copy
If you make any changes on your local copy, you can push them to your upstream using
[`dolt push`](/cli-reference/cli#dolt-push). Push to a feature branch rather than
@@ -127,7 +127,7 @@ You can also push straight to `main` if you'd rather skip review, subject to any
% dolt push origin --user "[username]" HEAD:main
```
-## 5. Open a pull request
+### 5. Open a pull request
Hosted Dolt doesn't have forks — that's a DoltHub and DoltLab feature. To contribute
a change for review, push a feature branch to the deployment (as in step 4 above) and
diff --git a/site/dolt/src/content/products/hosted/dolthub-as-remote.md b/site/dolt/src/content/products/hosted/dolthub-as-remote.md
index 5437d3eb..179435c6 100644
--- a/site/dolt/src/content/products/hosted/dolthub-as-remote.md
+++ b/site/dolt/src/content/products/hosted/dolthub-as-remote.md
@@ -40,7 +40,7 @@ pull, and fetch from public or private databases.
## Example
-## 1. Find a database on DoltHub to clone
+### 1. Find a database on DoltHub to clone
We have an example user metrics database on DoltHub named `dolthub/user_metrics`. Since we
don't want our metrics to be publicly accessible, the database is private.
@@ -49,7 +49,7 @@ We want to host this data on Hosted Dolt so that we can use [Google Looker
Studio](https://lookerstudio.google.com/) to visualize our data. Learn more about that
process [here](https://www.dolthub.com/blog/2023-02-13-dolt-looker/).
-## 2. Create a new deployment on Hosted
+### 2. Create a new deployment on Hosted
Next, I create a [new deployment](https://hosted.doltdb.com/create-deployment) on Hosted
and check the `Expose Dolt credentials` check box from the form.
@@ -65,14 +65,14 @@ will have access to this key.
If I accidentally expose my key or decide I want to remove it, I also have those options
there.
-## 3. Add public key to DoltHub
+### 3. Add public key to DoltHub
I click on "Add to DoltHub" to add my public key to DoltHub. This will open my DoltHub
[credentials settings page](https://www.dolthub.com/settings/credentials).

-## 4. Connect to Hosted instance and clone DoltHub database
+### 4. Connect to Hosted instance and clone DoltHub database
Now that I have my credentials set up, I can connect to the Hosted instance using the
information in the Connectivity tab and clone my `dolthub/user_metrics` database.
@@ -128,7 +128,7 @@ Now I can do whatever I want with my metrics data, including following [these
steps](https://www.dolthub.com/blog/2023-02-13-dolt-looker/#create-a-data-source) to
connect my Hosted instance to Looker.
-## 5. Make changes to database on DoltHub
+### 5. Make changes to database on DoltHub
Finance reviews our metrics charts and finds a hole in the data suggesting an outage.
@@ -139,7 +139,7 @@ editor and create a pull request. They don't even need to know SQL!

-## 6. Pull new DoltHub branch to Hosted instance for testing
+### 6. Pull new DoltHub branch to Hosted instance for testing
We want to review the new chart from the change before we merge it to `main`. We can pull
that branch to our Hosted instance and use it to [create a new branch in
@@ -167,7 +167,7 @@ mysql> select * from dolt_diff('main...outage-estimates', 'user_counts');
```
-## 7. Make a change from Hosted and push it back to DoltHub
+### 7. Make a change from Hosted and push it back to DoltHub
We are mostly satisfied with the new chart, but I want to make a small update to the
metrics for one of the days. I can make the change from Hosted on a branch and push it
@@ -207,7 +207,7 @@ I will see the new branch in my database on DoltHub.

-## 8. Merge branches into `main` on DoltHub and pull again to Hosted
+### 8. Merge branches into `main` on DoltHub and pull again to Hosted
From there, our changes are approved and merged into the `main` branch on DoltHub. One
more `dolt_pull` will update our `main` branch on Hosted.
diff --git a/site/dolt/src/content/products/hosted/getting-started.md b/site/dolt/src/content/products/hosted/getting-started.md
index e28df6b0..7850e98b 100644
--- a/site/dolt/src/content/products/hosted/getting-started.md
+++ b/site/dolt/src/content/products/hosted/getting-started.md
@@ -55,7 +55,7 @@ There are three ways to read or write from Hosted Dolt. You can:
In this blog, we will show off (1) and (2) but we're going to start with the Workbench because it is the easiest to use.
-## Start the Workbench
+### Start the Workbench
Click on the Workbench tab of your deployment.
@@ -67,7 +67,7 @@ The workbench has writes off by default. We will turn those on and create a data
This should feel like a standard SQL workbench like Tableplus or Datagrip but it's web-based and has some extra Dolt-specific features like a Commit Log and Pull Requests.
-## Create Some Tables
+### Create Some Tables
Now let's create some tables using SQL. We're going to enter the following SQL queries into the query box. You have to run them one at a time.
@@ -99,7 +99,7 @@ I finish up by subsequently running the last two create table queries.

-## Create a Dolt Commit
+### Create a Dolt Commit
Now time to use my first Dolt feature! I'm going to create a [Dolt Commit](/concepts/dolt/git/commits). Make a Dolt commit when you want to preserve the state of the Dolt database permanently for future reference.
@@ -145,7 +145,7 @@ Taylor can now access the deployment page to get connectivity information. Her m
Dolt is a MySQL-compatible database. You can connect any client that can connect to MySQL to it. We're going to use the MySQl client that comes with MySQL in this section to connect to Dolt.
-## Install
+### Install
Head over to the [MySQL Getting Started documentation](https://dev.mysql.com/doc/mysql-getting-started/en/) and install MySQL on your machine. I used [Homebrew](https://brew.sh/) to install MySQL on my Mac.
@@ -156,7 +156,7 @@ MySQL comes with a MySQL server called `mysqld` and a MySQL client called `mysql
mysql Ver 8.0.29 for macos12.2 on x86_64 (Homebrew)
```
-## Connect
+### Connect
Now, to connect the mysql client to Dolt, you need the host, port, username, and password from the Connectivity tab.
@@ -186,7 +186,7 @@ mysql>
This MySQL client is connected to your Hosted Dolt instance. Any changes you make here will be visible to users of the workbench or any other client connected to the Hosted Dolt database.
-## Create a branch
+### Create a branch
So let's be safe and make our changes on a [branch](/concepts/dolt/git/branch). A branch in Dolt is a lightweight way of isolating your changes from the "main" copy of the database. Since our goal is to make a Pull Request in the SQL Workbench, making a branch is necessary as pull requests are done between two branches, in this case "main" and our new branch.
@@ -216,7 +216,7 @@ mysql> select active_branch();
Great, Taylor is now on a new branch and can safely make her changes.
-## Insert some rows
+### Insert some rows
This is easy if you know SQL. In the MySQL client on the `inserts` branch, Taylor ran the following SQL to add a few of the early employees here at DoltHub and assign them to teams.
@@ -273,7 +273,7 @@ mysql> call dolt_commit('-m', 'inserted early employees');
Let's head back over to the workbench to make a Pull Request.
-## Make and Review a Pull Request
+### Make and Review a Pull Request
The Hosted Dolt workbench supports pull requests and human review of your Hosted Dolt database. Pull requests on Hosted are always opened and merged from the workbench — there are no forks (forks are a [DoltHub](/concepts/dolthub/prs) / [DoltLab](/products/doltlab) feature) and no CLI/SQL surface for opening a PR. The branch you're proposing for review can come from anywhere (the workbench, a MySQL client, a [local clone](/products/hosted/cloning), automation), but the PR itself is created in the web UI.
@@ -299,7 +299,7 @@ Finally, she clicks "Create pull request". She now sends me this Pull Request li

-## Review and Merge
+### Review and Merge
On the Pull Request Page, I have access to a human readable diff of the changes under review.
diff --git a/site/dolt/src/content/products/hosted/notable-features.md b/site/dolt/src/content/products/hosted/notable-features.md
index 48a38c4c..93b03648 100644
--- a/site/dolt/src/content/products/hosted/notable-features.md
+++ b/site/dolt/src/content/products/hosted/notable-features.md
@@ -18,21 +18,21 @@ example:
## Operations
-## Logs
+### Logs
While your database is running we collect logging so you can monitor your database. View
and download logs from any time period from the deployment console.

-## Monitoring
+### Monitoring
We also collect metrics on your running database and display graphs so you can see
performance and usage in real time.

-## Custom Configuration
+### Custom Configuration
Dolt has a myriad of [configuration options](/sql-reference/server/configuration).
Most of these can be changed on the running server by setting the appropriate [system
@@ -41,14 +41,14 @@ provides a simple UI for viewing and changing your deployment's custom configura

-## Replication
+### Replication
Scale your deployment read capacity or create hot failover instances by enabling read replication for your deployment. Configure how many replicas you want. You'll get
logs and metrics for each server.

-## Backups
+### Backups
Full copies of all your databases are backed up nightly. These backups are kept for 14
days.
@@ -66,14 +66,14 @@ requires you to create a support ticket.
Learn more about backups [here](https://www.dolthub.com/blog/2022-08-31-hosted-backups/).
-## Private Networking
+### Private Networking
Want to use Hosted Dolt, but don't want your database to be reachable through the public internet.
We support both AWS and GCP private networking.
[Private networking setup instructions](/products/hosted/private-networking)
-## Dolt Upgrades
+### Dolt Upgrades
We're releasing [new versions of Dolt](https://github.com/dolthub/dolt/releases) at least
once per week. Set your service window and your deployed Dolt version will automatically
@@ -84,7 +84,7 @@ get upgraded weekly to the latest available version with minimal downtime.
Or if you want to upgrade Dolt immediately, you can use the "Update Dolt version now"
button in the Actions dropdown.
-## Enterprise Support
+### Enterprise Support
Hosted Dolt comes with enterprise support. [Our team](https://www.dolthub.com/team) of
veteran cloud service engineers will keep your database operating smoothly.
@@ -97,7 +97,7 @@ will get back to you within the hour.
Learn more about our support ticket system
[here](https://www.dolthub.com/blog/2022-07-13-hosted-dolt-incident-manager/).
-## Access Management
+### Access Management
Easily manage access to your deployment using the same permissions model as
[DoltHub](/concepts/dolthub/permissions) and
@@ -121,7 +121,7 @@ a Branch Permissions UI. See
## Quick Start
-## Trial Instance
+### Trial Instance
To lower the cost barrier, Hosted Dolt offers [trial
instance](https://www.dolthub.com/blog/2022-10-24-hosted-trial-instances/) for $50 a
@@ -129,7 +129,7 @@ month. For $50 you get a t2.medium running in EC2 with 50GB of storage. There is
limit for these instances. This isn't a 30-day trial. It's an instance perfect for
trialing Dolt.
-## Connect Using Any MySQL Client
+### Connect Using Any MySQL Client
Dolt is a drop in replacement for MySQL. You can connect to your instance from anywhere
using your favorite MySQL client using the connectivity information in the Connectivity
@@ -139,7 +139,7 @@ tab of your deployment console.
## SQL Workbench
-## User Friendly Built-In Web GUI
+### User Friendly Built-In Web GUI
Each deployment comes with a built-in SQL workbench, inspired by
[DoltHub's](https://www.dolthub.com) database page. Browse your data in read-only mode or
@@ -151,31 +151,31 @@ favorite DoltHub features, including [pull requests](#pull-requests), [diffs](#d
Learn more about the SQL workbench [here](/products/hosted/sql-workbench).
-## Pull Requests
+### Pull Requests
Create pull requests for human review of changes to your database.

-## Diffs
+### Diffs
Analyze your data and schema changes in a diff and debug issues in specific commits.

-## Commit Log
+### Commit Log
View an audit log of all changes made to your data.

-## ER Diagrams
+### ER Diagrams
Visualize the entities in your database as well as the relationship between tables.

-## CSV Upload and Download
+### CSV Upload and Download
Update database tables using an uploaded CSV or the built-in spreadsheet editor.
@@ -189,7 +189,7 @@ Learn more in [our blog](https://www.dolthub.com/blog/2023-06-30-hosted-workbenc
## Dolt Ecosystem
-## Clone a Hosted Instance
+### Clone a Hosted Instance
In some cases you might want to clone your database from Hosted Dolt so that you can
access Dolt's [command line interface](/cli-reference/cli). Hosted provides an option
@@ -200,7 +200,7 @@ Hosted.
Learn more in our [cloning guide](/products/hosted/cloning).
-## Use DoltHub as a Remote
+### Use DoltHub as a Remote
To interact with DoltHub from your Hosted instance, you can use DoltHub as a
[remote](/concepts/dolt/git/remotes). We have [SQL
diff --git a/site/dolt/src/content/reference/sql/server/garbage-collection.md b/site/dolt/src/content/reference/sql/server/garbage-collection.md
index e3166ccf..67e5efa2 100644
--- a/site/dolt/src/content/reference/sql/server/garbage-collection.md
+++ b/site/dolt/src/content/reference/sql/server/garbage-collection.md
@@ -37,11 +37,11 @@ $ dolt sql --disable-auto-gc
Garbage collection can be run offline using [`dolt gc`](/cli-reference/cli#dolt-gc) or online using [`call dolt_gc()`](/sql-reference/version-control/dolt-sql-procedures#dolt_gc).
-## Offline
+### Offline
If you have access to the server where your Dolt database is located and a Dolt sql-server is not running, navigate to the directory your database is stored in and run `dolt gc`. This will cycle through all the needed chunks in your database and delete those that are unnecessary. This process is CPU and memory intensive.
-## Online, with Automatic GC disabled
+### Online, with Automatic GC disabled
If you have disabled Automatic GC, you can run garbage collection on your running SQL server using [`call dolt_gc`](/sql-reference/version-control/dolt-sql-procedures#dolt_gc) through any connected client. To prevent concurrent
writes potentially referencing garbage collected chunks, running
diff --git a/site/dolt/src/content/reference/sql/server/troubleshooting.md b/site/dolt/src/content/reference/sql/server/troubleshooting.md
index 4f01afc5..ad24ef40 100644
--- a/site/dolt/src/content/reference/sql/server/troubleshooting.md
+++ b/site/dolt/src/content/reference/sql/server/troubleshooting.md
@@ -7,27 +7,27 @@ Debugging a running Dolt server can be challenging. This document covers the deb
## Basics
-## Make sure you are running the latest Dolt version
+### Make sure you are running the latest Dolt version
Dolt is constantly evolving. We release a new Dolt approximately once a week. Connect to the SQL server and run `select dolt_version()`. Make sure the version matches the latest as seen on the [GitHub releases page](https://github.com/dolthub/dolt/releases).
To upgrade the server, download the latest Dolt binary for your platform and replace the Dolt binary on your `PATH` with the downloaded one. Running the install process on most platforms again will do this for you. Restart the Dolt server using `dolt sql-server` to have your running server start using the latest binary.
-## Examine your CPU, Memory, and Disk usage
+### Examine your CPU, Memory, and Disk usage
Dolt consumes CPU, Memory, and Disk. Consuming more of any of these resources than the host has available can lead to degraded performance. Use your system's built in resource monitoring systems to inspect Dolt's usage of these resources. You may need a larger host or additional [read replicas](/sql-reference/server/replication) to support your load.
-## Set your log level to DEBUG or TRACE
+### Set your log level to DEBUG or TRACE
To see queries being run against the server, query results, and query latency set your Dolt log level to `DEBUG` or `TRACE`. This can be done by starting the server like so `dolt sql-server --loglevel=debug` or by setting `log_level: debug` in your `config.yaml`. Your logs should be visible in the shell you started `dolt sql-server` in.
-## EXPLAIN PLAN for complex queries
+### EXPLAIN PLAN for complex queries
Dolt supports the SQL `EXPLAIN PLAN` operation in order for you to see the plan for complex queries. Rearranging your query to perform fewer `JOIN`s or make better use of indexes can help speed up complex queries.
Note: `EXPLAIN` currently returns MySQL-consistent but otherwise no-op output. Use `EXPLAIN PLAN` for Dolt formatted plans.
-## Compare to MySQL
+### Compare to MySQL
Dolt strives to be 100% MySQL compatible. If you run a query that works in MySQL but does not work in Dolt, it is a Dolt bug and you should [submit an issue](#submitting-issues). You can dump your Dolt database using [`dolt dump`](/cli-reference/cli#dolt-dump) and import the resulting file into MySQL using `mysql < dump.sql`. The test the query you think should work using any MySQL client.
@@ -39,7 +39,7 @@ If you run into any issues requiring engineering attention, please submit a [Git
Dolt operational issues usually manifest as slow SQL queries. In rare occasions, Dolt may consume more of your system's resources than you expect. In these cases, this document has some recommendations.
-## Server Consuming Disk
+### Server Consuming Disk
Dolt creates disk garbage on write. As of Dolt 1.75, automatic garbage collection is on by default. Thus, you should not experience disk garbage accumulation under normal operation for newer versions of Dolt.
@@ -50,7 +50,7 @@ Another potential cause is a commit-heavy workflow that uses a database design t
* Using primary keys with random values. Inserts into indexes with random values guarantees that edits will occur all throughout the index instead of being clustered around the same key space. This results in a rewrite of the Prolly Tree thereby increasing storage disproportionately to the delta of the changes.
* Adding a column to a table. A new column forks the storage of the table resulting in a loss of structural sharing. Dolt is row major and builds chunks for each primary key, row values pair. The row values encodes the schema length so every row now requires a new chunk.
-## Server Consuming Memory
+### Server Consuming Memory
Serving Dolt databases requires a fair amount of memory. As a general rule, we recommend a minimum
of 2GB available RAM for any production use case. Larger databases or heavier workloads should start
@@ -70,7 +70,7 @@ then frees the memory upon restart, you have discoverd a memory leak. Again, ple
issue](https://github.com/dolthub/dolt/issues). Memory leaks should be rare and we treat memory leak
fixes as high priority.
-## Server Consuming CPU
+### Server Consuming CPU
Under too much concurrent load, Dolt may consume all the CPU on a host. This is likely caused by too
much read concurrency. In this case, create more [read replicas](/sql-reference/server/replication) and load balance
@@ -79,7 +79,7 @@ your reads among your replicas.
If you discover a query consuming all of your CPU, please submit a [GitHub
Issue](https://github.com/dolthub/dolt/issues). On rare occasions, this could be a Dolt bug.
-## Too much write concurrency
+### Too much write concurrency
Currently, Dolt is not a high-throughput database for writes. The current transaction model
serializes all writes, which means that after a certain threshold of writer concurrency, you'll
diff --git a/site/dolt/src/content/reference/sql/sql-support/expressions-functions-operators.md b/site/dolt/src/content/reference/sql/sql-support/expressions-functions-operators.md
index e391f5ab..d40d970b 100644
--- a/site/dolt/src/content/reference/sql/sql-support/expressions-functions-operators.md
+++ b/site/dolt/src/content/reference/sql/sql-support/expressions-functions-operators.md
@@ -3,8 +3,6 @@ title: "Expressions, Functions, and Operators"
description: Supported scalar functions, operators, and expressions.
---
-## Expressions, Functions, Operators
-
## Statements
| Component | Supported | Notes and limitations |
diff --git a/site/dolt/src/nav.ts b/site/dolt/src/nav.ts
index ab77403b..1b82e75b 100644
--- a/site/dolt/src/nav.ts
+++ b/site/dolt/src/nav.ts
@@ -244,6 +244,20 @@ const nav: NavSection[] = [
{ title: "Infrastructure", href: "/products/hosted/infrastructure" },
{ title: "Private Networking", href: "/products/hosted/private-networking" },
{ title: "SSO", href: "/products/hosted/sso" },
+ {
+ // Only one API version exists, so the sections sit directly under
+ // API rather than behind a "v1" node. The paths keep /v1/ so a
+ // future v2 can be added without moving any of these URLs.
+ title: "API",
+ href: "/products/hosted/api",
+ children: [
+ { title: "Overview", href: "/products/hosted/api/v1" },
+ { title: "Authentication", href: "/products/hosted/api/v1/authentication" },
+ { title: "User", href: "/products/hosted/api/v1/user" },
+ { title: "Deployment", href: "/products/hosted/api/v1/deployment" },
+ { title: "Models", href: "/products/hosted/api/v1/models" },
+ ],
+ },
],
},
{
diff --git a/site/doltgres/src/content/reference/sql/server/troubleshooting.md b/site/doltgres/src/content/reference/sql/server/troubleshooting.md
index 94bfc92d..f75253ae 100644
--- a/site/doltgres/src/content/reference/sql/server/troubleshooting.md
+++ b/site/doltgres/src/content/reference/sql/server/troubleshooting.md
@@ -6,7 +6,7 @@ Debugging a running Doltgres server can be challenging. This document covers the
## Basics
-## Make sure you are running the latest Doltgres version
+### Make sure you are running the latest Doltgres version
Doltgres is constantly evolving. We release a new Doltgres approximately once a week. Connect to the
SQL server and run `select dolt_version()`. Make sure the version matches the latest as seen on the
@@ -14,15 +14,15 @@ SQL server and run `select dolt_version()`. Make sure the version matches the la
To upgrade the server, download the latest Doltgres binary for your platform and replace the Doltgres binary on your `PATH` with the downloaded one. Running the install process on most platforms again will do this for you. Restart the Doltgres server using `doltgres` to have your running server start using the latest binary.
-## Examine your CPU, Memory, and Disk usage
+### Examine your CPU, Memory, and Disk usage
Doltgres consumes CPU, Memory, and Disk. Consuming more of any of these resources than the host has available can lead to degraded performance. Use your system's built in resource monitoring systems to inspect Doltgres's usage of these resources. You may need a larger host or additional [read replicas](/reference/server/replication) to support your load.
-## Set your log level to DEBUG or TRACE
+### Set your log level to DEBUG or TRACE
To see queries being run against the server, query results, and query latency set your Doltgres log level to `DEBUG` or `TRACE`. This can be done by setting `log_level: debug` in your `config.yaml`. Your logs should be visible in the shell you started `doltgres` in.
-## Compare to Postgres
+### Compare to Postgres
Doltgres strives to be 100% Postgres compatible. If you run a query that works in Postgres but does not work in Doltgres, it is a Doltgres bug and you should [submit an issue](#submitting-issues). You can dump your Doltgres database using the `pg_dump` tool and import the resulting file into PostgreSQL. Then test the query you think should work against both servers using any Postgres client and compare the results.
@@ -34,7 +34,7 @@ If you run into any issues requiring engineering attention, please submit a [Git
Doltgres operational issues usually manifest as slow SQL queries. In rare occasions, Doltgres may consume more of your system's resources than you expect. In these cases, this document has some recommendations.
-## Server Consuming Disk
+### Server Consuming Disk
Doltgres creates disk garbage on write. This can sometimes become a substantial portion of the disk Doltgres is consuming. Doltgres ships with a garbage collection function. Running the garbage collection function can free disk.
@@ -47,7 +47,7 @@ Another potential cause is a commit-heavy workflow that uses a database design t
- Using primary keys with random values. Inserts into indexes with random values guarantees that edits will occur all throughout the index instead of being clustered around the same key space. This results in a rewrite of the prolly tree thereby increasing storage disproportionately to the delta of the changes.
- Adding a column to a table. A new column forks the storage of the table resulting in a loss of structural sharing. Doltgres is row major and builds chunks for each primary key, row values pair. The row values encodes the schema length so every row now requires a new chunk.
-## Server Consuming Memory
+### Server Consuming Memory
Serving Doltgres databases requires a fair amount of memory. As a general rule, we recommend a minimum
of 2GB available RAM for any production use case. Larger databases or heavier workloads should start
@@ -67,7 +67,7 @@ then frees the memory upon restart, you have discoverd a memory leak. Again, ple
issue](https://github.com/dolthub/doltgresql/issues). Memory leaks should be rare and we treat memory leak
fixes as high priority.
-## Server Consuming CPU
+### Server Consuming CPU
Under too much concurrent load, Doltgres may consume all the CPU on a host. This is likely caused by too
much read concurrency. In this case, create more [read replicas](/reference/server/replication) and load balance
@@ -76,7 +76,7 @@ your reads among your replicas.
If you discover a query consuming all of your CPU, please submit a [GitHub
Issue](https://github.com/dolthub/doltgresql/issues). On rare occasions, this could be a Doltgres bug.
-## Too much write concurrency
+### Too much write concurrency
Currently, Doltgres is not a high-throughput database for writes. The current transaction model
serializes all writes, which means that after a certain threshold of writer concurrency, you'll
diff --git a/site/doltlab/src/content/introduction/getting-started/getting-started.md b/site/doltlab/src/content/introduction/getting-started/getting-started.md
index 399ce21c..dc61ef5a 100644
--- a/site/doltlab/src/content/introduction/getting-started/getting-started.md
+++ b/site/doltlab/src/content/introduction/getting-started/getting-started.md
@@ -80,7 +80,7 @@ ubuntu@ip-10-2-0-24:~/doltlab$ ./ubuntu_install.sh
There are a few dependencies. This will take a couple minutes.
-## Make sure Docker works
+### Make sure Docker works
DoltLab uses Docker to run all of its services. After the bootstrap script is done, make sure Docker works with sudo by running:
@@ -197,7 +197,7 @@ The DoltLab instance ships with a default user configured called `admin`. It has
## Basic Configuration
-## Single user
+### Single user
A configured email server is required to create new users. If you try to create a user, you'll get an error that looks like this:
@@ -207,7 +207,7 @@ So, you only have a single admin user to play with for now.
> UPDATE: as of DoltLab v2.2.0, an email server is no longer required to create new users on a DoltLab instance. New users will be able to create accounts on an a DoltLab instance openly, unless [account whitelisting](/guides/basic#prevent-unauthorized-user-account-creation) has been enabled by the administrator. Additionally, email server configuration is now an exclusive [DoltLab Enterprise feature](/guides/enterprise#connect-doltlab-to-an-smtp-server).
-## Create/Modify databases
+### Create/Modify databases
You can build whatever database you can imagine using the web user interface. The built in SQL workbench can be used to create and edit tables. You can import CSVs. You can edit a table using the spreadsheet editor. You can make branches and Pull Requests.
@@ -215,7 +215,7 @@ Here's a simple test database I created using SQL.

-## Clone Databases
+### Clone Databases
DoltLab is a remote so you can clone databases from it. The remote API is exposed on port 50051. I made my test database public so I don't need any permissions to clone it.
@@ -236,7 +236,7 @@ $ dolt sql -q "select * from t"
I now have the test database I created on my DoltLab locally.
-## Push Databases
+### Push Databases
To push databases you need your Dolt client authenticated against your DoltLab instance. You can run a fresh `dolt login` against DoltLab using something like this:
@@ -279,26 +279,26 @@ You're now ready to try out all the Dolt and DoltLab experiences like Pull Reque
## Adding Additional Functionality
-## Create new users
+### Create new users
As discussed in [the single user section](#single-user), creating users in DoltLab <= `v2.1.6` requires a working SMTP server to send emails. However, DoltLab >= `v2.2.0` does not require an SMTP server connection in order for new users to create accounts on your DoltLab instance. In this newer version, an SMTP server connection can only be made with DoltLab Enterprise. For more information, consult [this guide to set up an email server for DoltLab](/guides/enterprise#set-up-a-smtp-server-using-any-gmail-address).
-## Receive Email Notifications
+### Receive Email Notifications
DoltLab Enterprise sends emails for password resets, pull request and issue status, and a few other use cases. Obviously, these also won't work without a running email server. Consult [this guide to set up an email server for DoltLab](/guides/enterprise#set-up-a-smtp-server-using-any-gmail-address).
-## HTTPS
+### HTTPS
Your DoltLab is currently set up to only use HTTP which is fairly insecure. If it's running on your internal network and you have other threat mitigations, this may be OK. But having it sit on the public internet on AWS without HTTPS is probably not what you want. Native HTTPS support is available in DoltLab Enterprise. [Learn how to set up HTTPS on your DoltLab here](/guides/enterprise#serve-doltlab-over-https-natively).
-## Custom URL
+### Custom URL
Right now, you're stuck hitting the IP address of your host. In order to use a custom URL on the internet, you need a static IP for your EC2 host and a domain name. If your host is running on an internal network, you may need to follow a different process.
-## Custom Logo/Colors
+### Custom Logo/Colors
Yay! Our first DoltLab Enterprise feature. If you would like a custom logo and color scheme for your DoltLab instance, you are going to need [DoltLab Enterprise](/guides/enterprise). DoltLab Enterprise is $5,000/month for unlimited users. It comes with Enterprise Support for Dolt as well. Among [other features](/guides/enterprise), DoltLab Enterprise allows you to customize the look and feel of your DoltLab instance. Learn how to [configure your DoltLab as Enterprise](/guides/enterprise) and [set up your custom look and feel here](/guides/enterprise#use-custom-logo).
-## Scalability
+### Scalability
Lastly, your DoltLab is running on a single host. All the components will scale to the size of that host including storing all the databases that are created. Storage and compute requirements can get big quickly. In order to break your DoltLab up into multiple instances and use cloud storage to store your databases, you need [DoltLab Enterprise](/guides/enterprise). Learn [how to set up Enterprise here](/guides/enterprise).
diff --git a/site/doltlab/src/content/older/pre-installer-administrator-guide.md b/site/doltlab/src/content/older/pre-installer-administrator-guide.md
index 0db1df3f..2ee59ecc 100644
--- a/site/doltlab/src/content/older/pre-installer-administrator-guide.md
+++ b/site/doltlab/src/content/older/pre-installer-administrator-guide.md
@@ -29,7 +29,7 @@ DoltLab persists all data to local disk using Docker volumes. To backup or resto
DoltLab <= `v0.8.4` uses PostgreSQL as its database and DoltLab `v1.0.0`+ uses Dolt. To backup the PostgreSQL server we recommend dumping the database with `pg_dump` and restoring the database from the dump using `psql`. To backup the Dolt server we recommend using Docker's volume backup and restore process, or Dolt's built-in backup and restore features.
-## Backing up and restoring remote data, user uploaded data, and Dolt server data with Docker
+### Backing up and restoring remote data, user uploaded data, and Dolt server data with Docker
To backup DoltLab's remote data, the database data for all database on a given DoltLab instance, leave DoltLab's services up and run:
@@ -141,7 +141,7 @@ docker run --rm --volumes-from doltlab_doltlabdb_1 -v $(pwd):/backup ubuntu bash
You can now restart DoltLab, and should see all data restored from the `tar` files.
-## Backing up and restoring PostgreSQL data
+### Backing up and restoring PostgreSQL data
For DoltLab versions <= `v0.8.4`, to backup data from DoltLab's postgres server, we recommend executing a data dump with `pg_dump`. To do so, keep DoltLab's services up and run:
@@ -197,7 +197,7 @@ SET session_replication_role = replica;
docker run --rm --network doltlab_doltlab -e PGPASSWORD= -v $(pwd):/doltlab-db-dumps postgres:13-bullseye bash -c "psql --host=doltlab_doltlabdb_1 --port=5432 --username=dolthubadmin dolthubapi < /doltlab-db-dumps/postgres-dump.sql"
```
-## Backing up and restoring the Dolt server with `dolt backup`
+### Backing up and restoring the Dolt server with `dolt backup`
DoltLab `v1.0.0`+ uses Dolt as its database. To back up the Dolt server of DoltLab using Dolt's built-in backup and restore features, keep DoltLab's services up and open a connection to the database. The quickest way to do this is with the `./shell-db.sh` script included with DoltLab:
@@ -592,7 +592,7 @@ Starting with DoltLab `v1.0.0`, DoltLab can be configured to use a [Hosted Dolt]
To configure a DoltLab to use a Hosted Dolt, follow the steps below as we create a sample DoltLab Hosted Dolt instance called `my-doltlab-db-1`.
-## Create a Hosted Dolt deployment
+### Create a Hosted Dolt deployment
To begin, you'll need to create a Hosted Dolt deployment that your DoltLab instance will connect to. We've created a [video tutorial](https://www.dolthub.com/blog/2022-05-20-hosted-dolt-howto/) for how to create your first Hosted Dolt deployment, but briefly, you'll need to create an account on [hosted.doltdb.com](https://hosted.doltdb.com) and then click the "Create Deployment" button.
@@ -639,7 +639,7 @@ You can do this by running these statements from the Hosted workbench SQL consol
This instance is now ready for a DoltLab connection.
-## Edit DoltLab's Docker Compose file
+### Edit DoltLab's Docker Compose file
To connect DoltLab to `my-doltlab-db-1`, ensure that your DoltLab instance is stopped, and remove references to `doltlabdb` in DoltLab's `docker-compose.yaml` file.
diff --git a/specs/hosted-v1.yaml b/specs/hosted-v1.yaml
new file mode 100644
index 00000000..56bb91cd
--- /dev/null
+++ b/specs/hosted-v1.yaml
@@ -0,0 +1,1508 @@
+# Hosted Public API v1 — OpenAPI contract.
+#
+# This is the single source of truth for the v1 API. TypeScript DTO types,
+# runtime/contract-test JSON Schemas, and the public docs are all generated
+# from this file — never hand-edited downstream.
+#
+# The error model, envelope, and pagination conventions below are deliberately
+# identical to DoltHub's v2 spec (web/packages/dolthub/openapi/v2.yaml) apart
+# from the docs URL. Two public APIs from the same company that disagree about
+# error bodies is a worse outcome than either individual choice.
+openapi: 3.1.0
+
+info:
+ title: Hosted API
+ version: 1.0.0
+ summary: The public REST API for Hosted Dolt deployments.
+ description: |
+ The Hosted v1 API is an explicit, versioned, OpenAPI-defined contract for the Hosted
+ control plane: deployments and their instances, backups, credentials, configuration,
+ and access.
+
+ This document is the contract: it is the source of truth for the implementation, the
+ generated types, and the rendered reference docs.
+
+ **Scope.** v1 covers the control plane only. Querying the data inside a deployment is
+ not part of this API — every deployment exposes a SQL endpoint that callers connect to
+ directly with their own credentials.
+ contact:
+ name: DoltHub Support
+ url: https://hosted.doltdb.com/contact
+ email: dolt-interest@dolthub.com
+ license:
+ name: Hosted Dolt Terms of Service
+ url: https://hosted.doltdb.com/terms
+ termsOfService: https://hosted.doltdb.com/terms
+
+servers:
+ - url: https://hosted.doltdb.com
+ description: Production
+
+# Default: every operation requires an API token. Individual operations may override this
+# once paths are added. API tokens are the only credential in v1 — the scheme list is a
+# sequence so an `oauth2` scheme can be added later without a breaking change.
+security:
+ - apiToken: []
+
+# Operation tags are registered here so renderers group operations consistently.
+tags:
+ - name: User
+ description: The authenticated user.
+ - name: Deployment
+ description: Hosted Dolt deployments and their lifecycle.
+
+paths:
+ /api/v1/user:
+ get:
+ operationId: getCurrentUser
+ summary: Get the authenticated user.
+ description: >-
+ Returns the profile of the user identified by the request's credentials. Useful as a
+ credential check: a `200` confirms the token is valid and shows whose access it
+ carries.
+ tags:
+ - User
+ security:
+ - apiToken: []
+ responses:
+ "200":
+ description: The authenticated user's profile.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/Envelope"
+ - type: object
+ required:
+ - data
+ properties:
+ data:
+ $ref: "#/components/schemas/User"
+ examples:
+ default:
+ summary: An authenticated user's profile.
+ value:
+ data:
+ username: acme-ops
+ display_name: Acme Operations
+ company: Acme Corp
+ email_addresses:
+ - address: ops@acme.com
+ is_verified: true
+ is_primary: true
+ "401":
+ $ref: "#/components/responses/Unauthorized"
+ "405":
+ $ref: "#/components/responses/MethodNotAllowed"
+ "500":
+ $ref: "#/components/responses/InternalServerError"
+
+ /api/v1/deployment-options:
+ get:
+ operationId: getDeploymentOptions
+ summary: List the options a deployment can be created with.
+ description: >-
+ Returns the zones, instance types, and storage options available for a cloud, so a
+ caller can construct a valid `POST /api/v1/deployments` request.
+
+
+ The options narrow in steps, because each depends on the one before it. Supply
+ `cloud` alone for its zones; add `zone` to also get that zone's instance types; add
+ `instance_type_id` to also get the storage options compatible with that instance.
+ Fields you haven't narrowed enough to determine are absent rather than empty.
+
+
+ Each list is filtered to what you selected: supplying `zone` narrows `zones` to that
+ zone, and supplying `instance_type_id` narrows `instance_types` to that instance
+ type. A fully narrowed request therefore describes one combination rather than
+ repeating the whole catalogue.
+
+
+ A `zone` or `instance_type_id` that doesn't exist is a `422` rather than an empty
+ result, so a typo can't be mistaken for a combination with nothing available.
+ `instance_type_id` requires `zone`; supplying it alone is a `400`.
+
+
+ The `id` of an instance type or storage option is what
+ `POST /api/v1/deployments` accepts; `name` is for display.
+ tags:
+ - Deployment
+ security:
+ - apiToken: []
+ parameters:
+ - name: cloud
+ in: query
+ required: true
+ description: The cloud to list options for.
+ schema:
+ $ref: "#/components/schemas/CloudProvider"
+ - name: zone
+ in: query
+ required: false
+ description: >-
+ A zone from this cloud's `zones`. Supply it to receive `instance_types`.
+ schema:
+ type: string
+ minLength: 1
+ example: us-east-1
+ - name: instance_type_id
+ in: query
+ required: false
+ description: >-
+ An instance type `id` from `instance_types`. Supply it, together with `zone`,
+ to receive `storage_options`.
+ schema:
+ type: string
+ minLength: 1
+ example: aws.t2.medium
+ responses:
+ "200":
+ description: The available options, narrowed by the supplied parameters.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/Envelope"
+ - type: object
+ required:
+ - data
+ properties:
+ data:
+ $ref: "#/components/schemas/DeploymentOptions"
+ examples:
+ default:
+ summary: Fully narrowed options for one instance type.
+ value:
+ data:
+ cloud: aws
+ zones:
+ - us-east-1
+ instance_types:
+ - id: aws.t2.medium
+ name: t2.medium
+ cpus: 2
+ memory_gb: 4
+ description: Trial tier, the lowest spec that runs a Dolt SQL server.
+ hourly_cost_usd: 0.06849315
+ storage_options:
+ - id: aws.ebs.gp3_50
+ name: Trial 50GB EBS
+ description: Trial tier storage capped at 50GB
+ min_size_gb: 50
+ max_size_gb: 50
+ monthly_cost_usd_per_gb: 0
+ "400":
+ $ref: "#/components/responses/BadRequest"
+ "401":
+ $ref: "#/components/responses/Unauthorized"
+ "405":
+ $ref: "#/components/responses/MethodNotAllowed"
+ "422":
+ $ref: "#/components/responses/UnprocessableEntity"
+ "500":
+ $ref: "#/components/responses/InternalServerError"
+ "503":
+ $ref: "#/components/responses/ServiceUnavailable"
+
+ /api/v1/deployments:
+ post:
+ operationId: createDeployment
+ summary: Create a deployment.
+ description: >-
+ Provisions a new deployment and returns `202` with the deployment in its `starting`
+ state. Provisioning continues after the response: poll
+ `GET /api/v1/deployments/{owner}/{deployment}` until `state` becomes `started`.
+
+
+ Deployment names are unique within an owner, so a create is idempotent by name — a
+ retry after an ambiguous failure returns `409` rather than provisioning a second
+ deployment. Callers should still treat `409` as "it already exists", not as a
+ different failure.
+
+
+ `instance_type_id` and `volume_type_id` take the **ids** from the deployment options
+ endpoint, not the display names a deployment reports back on a read.
+
+
+ As with any create, a `5xx` or a dropped connection does not tell you whether the
+ deployment was created — the call can succeed remotely and fail on the way back.
+ Retry: it returns `409` if the deployment now exists, and `GET` confirms either way.
+
+
+ **Creating a deployment incurs cost.**
+ tags:
+ - Deployment
+ security:
+ - apiToken: []
+ requestBody:
+ required: true
+ description: The provisioning parameters for the new deployment.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/CreateDeploymentRequest"
+ examples:
+ default:
+ summary: A single-instance Dolt deployment on AWS.
+ value:
+ owner: acme
+ name: analytics
+ cloud: aws
+ zone: us-east-1
+ instance_type_id: aws.t2.medium
+ volume_type_id: aws.ebs.gp3_50
+ volume_size_gb: 50
+ responses:
+ "202":
+ description: >-
+ The deployment has been accepted and is provisioning. `state` is `starting`.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/Envelope"
+ - type: object
+ required:
+ - data
+ properties:
+ data:
+ $ref: "#/components/schemas/Deployment"
+ examples:
+ default:
+ summary: A deployment accepted and provisioning.
+ value:
+ data:
+ owner: acme
+ name: analytics
+ state: starting
+ cloud: aws
+ zone: us-east-1
+ cluster_type: dolt
+ instance_type_name: t2.medium
+ volume_type_name: Trial 50GB EBS
+ volume_size_gb: 50
+ replicas: 0
+ host: ""
+ port: 3306
+ caller_role: admin
+ created_by: acme-ops
+ created_at: "2026-08-11T09:14:00Z"
+ "400":
+ $ref: "#/components/responses/BadRequest"
+ "401":
+ $ref: "#/components/responses/Unauthorized"
+ "403":
+ $ref: "#/components/responses/Forbidden"
+ "405":
+ $ref: "#/components/responses/MethodNotAllowed"
+ "409":
+ $ref: "#/components/responses/Conflict"
+ "422":
+ $ref: "#/components/responses/UnprocessableEntity"
+ "500":
+ $ref: "#/components/responses/InternalServerError"
+ "503":
+ $ref: "#/components/responses/ServiceUnavailable"
+
+ /api/v1/deployments/{owner}:
+ get:
+ operationId: listDeployments
+ summary: List an owner's deployments.
+ description: >-
+ Returns the deployments belonging to `{owner}` that the caller can see, newest
+ cursor page first. Requires a credential with access to the owner.
+
+
+ Items are `DeploymentSummary`, not the full `Deployment` — the backing RPC returns a
+ narrower shape for lists. Fetch
+ `GET /api/v1/deployments/{owner}/{deployment}` for the complete resource.
+
+
+ Pagination is cursor-based: when `meta.next_page_token` is present, pass it back as
+ `page_token` to fetch the next page. On the last page `meta` is omitted entirely, so
+ presence of the token is the only check a client needs.
+ tags:
+ - Deployment
+ security:
+ - apiToken: []
+ parameters:
+ - name: owner
+ in: path
+ required: true
+ description: >-
+ The user or organization whose deployments to list. 3–32 characters of letters,
+ digits, hyphens, and underscores.
+ schema:
+ type: string
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ example: acme
+ - name: page_token
+ in: query
+ required: false
+ description: >-
+ The `meta.next_page_token` from a previous response. Omit for the first page.
+ schema:
+ type: string
+ example: eyJvZmZzZXQiOjI1fQ
+ - name: state
+ in: query
+ required: false
+ description: Return only deployments in this state. Omit for all states.
+ schema:
+ $ref: "#/components/schemas/DeploymentState"
+ responses:
+ "200":
+ description: The owner's deployments.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/Envelope"
+ - type: object
+ required:
+ - data
+ properties:
+ data:
+ type: array
+ description: The page of deployments.
+ items:
+ $ref: "#/components/schemas/DeploymentSummary"
+ examples:
+ default:
+ summary: One page of deployments.
+ value:
+ data:
+ - owner: acme
+ name: analytics
+ state: started
+ cloud: aws
+ zone: us-west-2
+ cluster_type: dolt
+ instance_type_name: m5.large
+ volume_type_name: gp3
+ volume_size_gb: 100
+ replicas: 0
+ database_version: 1.58.4
+ hourly_cost_usd: 0.192
+ webpki_cert: true
+ meta:
+ next_page_token: eyJvZmZzZXQiOjI1fQ
+ "400":
+ $ref: "#/components/responses/BadRequest"
+ "401":
+ $ref: "#/components/responses/Unauthorized"
+ "403":
+ $ref: "#/components/responses/Forbidden"
+ "404":
+ $ref: "#/components/responses/NotFound"
+ "405":
+ $ref: "#/components/responses/MethodNotAllowed"
+ "500":
+ $ref: "#/components/responses/InternalServerError"
+
+ /api/v1/deployments/{owner}/{deployment}:
+ get:
+ operationId: getDeployment
+ summary: Get a deployment.
+ description: >-
+ Returns the deployment `{owner}/{deployment}`. Requires a credential with at least
+ read access; a deployment the caller cannot see returns `404` rather than `403`, so
+ its existence isn't leaked.
+ tags:
+ - Deployment
+ security:
+ - apiToken: []
+ parameters:
+ - name: owner
+ in: path
+ required: true
+ description: >-
+ The user or organization that owns the deployment. 3–32 characters of letters,
+ digits, hyphens, and underscores.
+ schema:
+ type: string
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ example: acme
+ - name: deployment
+ in: path
+ required: true
+ description: >-
+ The deployment name, unique within the owner. 3–32 characters of letters,
+ digits, hyphens, and underscores.
+ schema:
+ type: string
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ example: analytics
+ responses:
+ "200":
+ description: The deployment.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/Envelope"
+ - type: object
+ required:
+ - data
+ properties:
+ data:
+ $ref: "#/components/schemas/Deployment"
+ examples:
+ default:
+ summary: A running deployment.
+ value:
+ data:
+ owner: acme
+ name: analytics
+ state: started
+ cloud: aws
+ zone: us-east-1
+ cluster_type: dolt
+ instance_type_name: t2.medium
+ volume_type_name: Trial 50GB EBS
+ volume_size_gb: 50
+ replicas: 0
+ database_version: 1.58.4
+ host: analytics.dbs.hosted.doltdb.com
+ port: 3306
+ hourly_cost_usd: 0.06849315
+ webpki_cert: true
+ expose_remotesapi_endpoint: false
+ expose_mcp: false
+ expose_stats: false
+ disable_automatic_dolt_updates: false
+ caller_role: admin
+ created_by: acme-ops
+ created_at: "2026-07-01T18:22:04Z"
+ "400":
+ $ref: "#/components/responses/BadRequest"
+ "401":
+ $ref: "#/components/responses/Unauthorized"
+ "404":
+ $ref: "#/components/responses/NotFound"
+ "405":
+ $ref: "#/components/responses/MethodNotAllowed"
+ "500":
+ $ref: "#/components/responses/InternalServerError"
+ "503":
+ $ref: "#/components/responses/ServiceUnavailable"
+
+ /api/v1/deployments/{owner}/{deployment}/instances:
+ get:
+ operationId: listDeploymentInstances
+ summary: List a deployment's instances.
+ description: >-
+ Returns the instances backing `{owner}/{deployment}` — one for a single-instance
+ deployment, or a primary plus its read replicas.
+
+
+ Stopped instances are not listed; starting, started, and stopping ones all are. So
+ an instance appearing here is part of the deployment but not necessarily serving
+ traffic, and an empty array means it has none outside the stopped state — normal
+ while a deployment is itself `starting`.
+
+
+ The list is not paginated: a deployment has a primary and its replicas, a set small
+ enough to return whole.
+ tags:
+ - Deployment
+ security:
+ - apiToken: []
+ parameters:
+ - name: owner
+ in: path
+ required: true
+ description: >-
+ The user or organization that owns the deployment. 3–32 characters of letters,
+ digits, hyphens, and underscores.
+ schema:
+ type: string
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ example: acme
+ - name: deployment
+ in: path
+ required: true
+ description: >-
+ The deployment name, unique within the owner. 3–32 characters of letters,
+ digits, hyphens, and underscores.
+ schema:
+ type: string
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ example: analytics
+ responses:
+ "200":
+ description: The deployment's non-stopped instances.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/json:
+ schema:
+ allOf:
+ - $ref: "#/components/schemas/Envelope"
+ - type: object
+ required:
+ - data
+ properties:
+ data:
+ type: array
+ description: The deployment's non-stopped instances.
+ items:
+ $ref: "#/components/schemas/DeploymentInstance"
+ examples:
+ default:
+ summary: A primary with one read replica.
+ value:
+ data:
+ - id: 9b1f5c2e-4d3a-4f8b-9c0d-1e2f3a4b5c6d
+ index: 0
+ is_primary: true
+ host: analytics-0.dbs.hosted.doltdb.com
+ instance_type_name: t2.medium
+ volume_type_name: Trial 50GB EBS
+ volume_size_gb: 50
+ hourly_cost_usd: 0.06849315
+ - id: 2c4e6a8b-1d3f-4a5c-8e9b-0f1a2b3c4d5e
+ index: 1
+ is_primary: false
+ host: analytics-1.dbs.hosted.doltdb.com
+ instance_type_name: t2.medium
+ volume_type_name: Trial 50GB EBS
+ volume_size_gb: 50
+ hourly_cost_usd: 0.06849315
+ "400":
+ $ref: "#/components/responses/BadRequest"
+ "401":
+ $ref: "#/components/responses/Unauthorized"
+ "404":
+ $ref: "#/components/responses/NotFound"
+ "405":
+ $ref: "#/components/responses/MethodNotAllowed"
+ "500":
+ $ref: "#/components/responses/InternalServerError"
+ "503":
+ $ref: "#/components/responses/ServiceUnavailable"
+
+components:
+ headers:
+ RequestId:
+ description: >-
+ The request identifier — echoed on every response (including 2xx). Reuse
+ the inbound `x-request-id` from the caller / edge proxy when present;
+ otherwise the server mints a `req_` value.
+ schema:
+ type: string
+ examples:
+ - req_2f1c9e7a-3b6d-4c5e-8a9f-0d1e2f3a4b5c
+
+ securitySchemes:
+ apiToken:
+ type: http
+ scheme: bearer
+ description: >-
+ A Hosted API token, sent as `Authorization: Bearer `. Create one from the
+ Tokens section of your account settings. Tokens carry the full permissions of the
+ user who created them and expire on a date chosen at creation.
+
+ schemas:
+ # --- Error model ---------------------------------------------------------------------
+ # Every non-2xx response uses Problem (RFC 9457).
+ ErrorCode:
+ type: string
+ title: ErrorCode
+ description: >-
+ A stable, machine-readable error code in SCREAMING_SNAKE_CASE. Clients branch on
+ this value, never on the human-readable `title`/`detail` prose. The baseline codes
+ below cover the standard HTTP failure categories; endpoint-specific codes (e.g.
+ `DEPLOYMENT_NOT_FOUND`) are appended to this enum alongside the endpoints that emit
+ them, which is an additive, non-breaking change under the v1 stability policy.
+ enum:
+ - VALIDATION_FAILED # 400 — malformed request or failed input validation
+ - UNAUTHENTICATED # 401 — missing or invalid credentials
+ - PERMISSION_DENIED # 403 — authenticated but not permitted
+ - NOT_FOUND # 404 — resource does not exist
+ - METHOD_NOT_ALLOWED # 405 — HTTP method not supported for this resource
+ - CONFLICT # 409 — conflicts with current state (e.g. already exists)
+ - UNPROCESSABLE # 422 — well-formed but semantically invalid
+ - RATE_LIMITED # 429 — rate limit exceeded
+ - INTERNAL # 500 — unexpected server fault
+ - SERVICE_UNAVAILABLE # 503 — temporarily unavailable
+ - OPERATION_FAILED # operation reached terminal failure state
+ examples:
+ - NOT_FOUND
+
+ Problem:
+ type: object
+ title: Problem
+ description: >-
+ A structured error body returned for every non-2xx response, following RFC 9457
+ (Problem Details for HTTP APIs). This is the single error model for the entire v1
+ API — there are no ad-hoc error shapes.
+ required:
+ # `type` is required even though RFC 9457 permits omitting it: this API always emits
+ # it, and leaving it optional made the spec disagree with the generated DTO (which
+ # marks it non-optional because of the `default`).
+ - type
+ - title
+ - status
+ - code
+ - request_id
+ properties:
+ type:
+ type: string
+ format: uri
+ default: about:blank
+ description: >-
+ A URI identifying the problem type; when dereferenced it points at
+ human-readable documentation for the error.
+ examples:
+ - https://docs.dolthub.com/products/hosted/api/v1/models/#model-errorcode
+ title:
+ type: string
+ description: A short, human-readable summary of the problem type.
+ examples:
+ - Not found
+ status:
+ type: integer
+ format: int32
+ minimum: 400
+ maximum: 599
+ description: The HTTP status code, repeated in the body for convenience.
+ examples:
+ - 404
+ detail:
+ type: string
+ description: A human-readable explanation specific to this occurrence of the problem.
+ examples:
+ - "Deployment 'analytics' does not exist for owner 'acme'"
+ instance:
+ type: string
+ format: uri-reference
+ description: A URI reference identifying the specific occurrence (typically the request path).
+ examples:
+ - /api/v1/deployments/acme/analytics
+ code:
+ $ref: "#/components/schemas/ErrorCode"
+ request_id:
+ type: string
+ description: >-
+ The request identifier, echoed on every response. Include it when contacting
+ support so a request can be traced end-to-end.
+ examples:
+ - req_01HZX9P7Q5N2M8
+ additionalProperties: true
+
+ # --- Success envelope ----------------------------------------------------------------
+ Meta:
+ type: object
+ title: Meta
+ description: >-
+ Response metadata carried alongside the primary `data` payload. All fields are
+ optional; list endpoints populate `next_page_token` for cursor pagination.
+ properties:
+ next_page_token:
+ type: string
+ description: >-
+ Opaque cursor for the next page of a list response. Absent when there are no
+ further results — never present and empty — otherwise pass it back as the
+ `page_token` query parameter to fetch the next page.
+ examples:
+ - eyJvZmZzZXQiOjI1fQ
+ additionalProperties: true
+ examples:
+ - next_page_token: eyJvZmZzZXQiOjI1fQ
+
+ Envelope:
+ type: object
+ title: Envelope
+ description: >-
+ The success envelope wrapping every 2xx response body: the resource or list of
+ resources under `data`, with optional `meta`. This is the single success shape for
+ the API — there are no unenveloped success bodies. Endpoints narrow `data` to a
+ concrete resource via `allOf`; the base leaves `data` unconstrained so that
+ composition works.
+ required:
+ - data
+ properties:
+ data:
+ type: [object, array]
+ # Required for `data` to actually be unconstrained. Without it, openapi-typescript
+ # emits `Record` — an object permitting no properties — and the
+ # composed `Envelope & { data: Resource }` becomes unassignable, so nothing can use
+ # the generated response type.
+ additionalProperties: true
+ description: The primary response payload — a resource, or an array of resources for list endpoints.
+ meta:
+ $ref: "#/components/schemas/Meta"
+ examples:
+ - data:
+ username: acme-ops
+ meta:
+ next_page_token: eyJvZmZzZXQiOjI1fQ
+
+ # --- Resources ----------------------------------------------------------------------
+ # Resource schemas are the public DTO surface — what the v1 contract guarantees to
+ # integrators. Field names are snake_case. Fields are added additively under the v1
+ # stability policy; renames or removals require v2.
+ UserEmailAddress:
+ type: object
+ title: UserEmailAddress
+ description: An email address belonging to a user.
+ required:
+ - address
+ - is_verified
+ - is_primary
+ properties:
+ address:
+ type: string
+ description: The email address.
+ examples:
+ - ops@acme.com
+ is_verified:
+ type: boolean
+ description: Whether the address has completed email verification.
+ is_primary:
+ type: boolean
+ description: >-
+ Whether this is the user's primary address. Exactly one address is primary.
+ User:
+ type: object
+ title: User
+ description: >-
+ A Hosted user. `GET /api/v1/user` returns the authenticated user's profile. v1
+ returns only public-facing profile fields — the identity provider the account signs
+ in with, session state, and credential metadata are never included.
+ required:
+ - username
+ - email_addresses
+ properties:
+ username:
+ type: string
+ description: The user's Hosted username (unique handle).
+ examples:
+ - acme-ops
+ display_name:
+ type: string
+ description: The user's display name. May be empty.
+ examples:
+ - Acme Operations
+ company:
+ type: string
+ description: The user's stated company. May be empty.
+ examples:
+ - Acme Corp
+ email_addresses:
+ type: array
+ description: >-
+ The user's email addresses. Returned only for the authenticated user
+ themselves; empty for any other caller.
+ items:
+ $ref: "#/components/schemas/UserEmailAddress"
+
+ InstanceType:
+ type: object
+ title: InstanceType
+ description: A compute instance type a deployment can run on.
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: string
+ description: >-
+ The identifier `POST /api/v1/deployments` accepts as `instance_type_id`.
+ examples:
+ - aws.t2.medium
+ name:
+ type: string
+ description: The display name. A deployment reports this as `instance_type_name`.
+ examples:
+ - t2.medium
+ cpus:
+ type: integer
+ format: int32
+ description: Virtual CPUs.
+ examples:
+ - 2
+ memory_gb:
+ type: integer
+ format: int32
+ description: Memory, in gigabytes.
+ examples:
+ - 4
+ description:
+ type: string
+ description: A human-readable summary of what the instance suits.
+ examples:
+ - Trial tier, the lowest spec that runs a Dolt SQL server.
+ hourly_cost_usd:
+ type: number
+ format: float
+ description: >-
+ Cost per hour in US dollars. Absent when no hourly price is published for this
+ instance type.
+ examples:
+ - 0.06849315
+
+ StorageOption:
+ type: object
+ title: StorageOption
+ description: A storage type a deployment's volume can use.
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: string
+ description: >-
+ The identifier `POST /api/v1/deployments` accepts as `volume_type_id`.
+ examples:
+ - aws.ebs.gp3_50
+ name:
+ type: string
+ description: The display name. A deployment reports this as `volume_type_name`.
+ examples:
+ - Trial 50GB EBS
+ description:
+ type: string
+ description: A human-readable summary of the storage type.
+ examples:
+ - Trial tier storage capped at 50GB
+ min_size_gb:
+ type: integer
+ format: int32
+ description: >-
+ Smallest volume size this type supports, in gigabytes. `volume_size_gb` on a
+ create request must be at least this.
+ examples:
+ - 50
+ max_size_gb:
+ type: integer
+ format: int32
+ description: >-
+ Largest volume size this type supports, in gigabytes.
+ examples:
+ - 50
+ monthly_cost_usd_per_gb:
+ type: number
+ format: float
+ description: Cost per gigabyte per month, in US dollars.
+ examples:
+ - 0
+
+ DeploymentInstance:
+ type: object
+ title: DeploymentInstance
+ description: >-
+ One instance backing a deployment. A deployment has a primary and, when it has read
+ replicas, one instance per replica.
+ required:
+ - id
+ - index
+ - is_primary
+ properties:
+ id:
+ type: string
+ format: uuid
+ description: The instance's identifier, unique within the deployment.
+ examples:
+ - 9b1f5c2e-4d3a-4f8b-9c0d-1e2f3a4b5c6d
+ index:
+ type: integer
+ format: int32
+ description: >-
+ The instance's position in the deployment. `0` is the first instance; replicas
+ take the following indices.
+ examples:
+ - 0
+ is_primary:
+ type: boolean
+ description: >-
+ Whether this instance is currently the primary. Exactly one instance of a
+ started deployment is primary, and which one can change over the deployment's
+ life.
+ examples:
+ - true
+ host:
+ type: string
+ description: >-
+ The hostname for this specific instance. Connect to the deployment's own `host`
+ unless you mean to address one instance directly.
+ examples:
+ - analytics-0.dbs.hosted.doltdb.com
+ instance_type_name:
+ type: string
+ description: The display name of this instance's type.
+ examples:
+ - t2.medium
+ volume_type_name:
+ type: string
+ description: The display name of this instance's storage type.
+ examples:
+ - Trial 50GB EBS
+ volume_size_gb:
+ type: integer
+ format: int32
+ description: The size of this instance's storage volume, in gigabytes.
+ examples:
+ - 50
+ hourly_cost_usd:
+ type: number
+ format: float
+ description: >-
+ This instance's cost per hour, in US dollars. A deployment's total is the sum
+ across its instances.
+ examples:
+ - 0.06849315
+
+ DeploymentOptions:
+ type: object
+ title: DeploymentOptions
+ description: >-
+ The options available for creating a deployment, narrowed by the query parameters
+ supplied. `instance_types` and `storage_options` are absent until enough of the
+ chain has been supplied to determine them.
+ required:
+ - cloud
+ - zones
+ properties:
+ cloud:
+ $ref: "#/components/schemas/CloudProvider"
+ zones:
+ type: array
+ description: The zones this cloud supports.
+ items:
+ type: string
+ examples:
+ - ["us-east-1", "us-west-2", "eu-west-2"]
+ instance_types:
+ type: array
+ description: >-
+ Instance types available in the requested `zone`. Absent when `zone` wasn't
+ supplied.
+ items:
+ $ref: "#/components/schemas/InstanceType"
+ storage_options:
+ type: array
+ description: >-
+ Storage types compatible with the requested `instance_type_id`. Absent when
+ `zone` and `instance_type_id` weren't both supplied.
+ items:
+ $ref: "#/components/schemas/StorageOption"
+
+ CreateDeploymentRequest:
+ type: object
+ title: CreateDeploymentRequest
+ description: >-
+ The provisioning parameters for a new deployment.
+
+
+ v1.0 exposes the core parameters only. Restoring from a backup, cloning an existing
+ deployment, workbench user settings, and private networking are all settable on the
+ internal API but are not part of this request; each is its own feature with its own
+ contract, and adding them is additive. The internal deployment test flag is
+ deliberately not exposed at all.
+ required:
+ - owner
+ - name
+ - cloud
+ - zone
+ - instance_type_id
+ - volume_type_id
+ - volume_size_gb
+ properties:
+ owner:
+ type: string
+ description: >-
+ The user or organization that will own the deployment. The caller must have
+ permission to create deployments for it. 3–32 characters of letters, digits,
+ hyphens, and underscores.
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ examples:
+ - acme
+ name:
+ type: string
+ description: >-
+ The deployment name, unique within the owner. 3–32 characters of letters,
+ digits, hyphens, and underscores.
+ pattern: "^[-a-zA-Z0-9_]{3,32}$"
+ examples:
+ - analytics
+ cloud:
+ $ref: "#/components/schemas/CloudProvider"
+ zone:
+ type: string
+ description: The cloud region to provision in, as listed by the deployment options.
+ minLength: 1
+ examples:
+ - us-east-1
+ cluster_type:
+ $ref: "#/components/schemas/ClusterType"
+ instance_type_id:
+ type: string
+ description: >-
+ The **id** of the instance type, from the deployment options endpoint. Note a
+ deployment reports `instance_type_name` on a read — the id and the display name
+ are different values.
+ minLength: 1
+ examples:
+ - aws.t2.medium
+ volume_type_id:
+ type: string
+ description: >-
+ The **id** of the storage type, from the deployment options endpoint. As with
+ `instance_type_id`, this is the id rather than the display name.
+ minLength: 1
+ examples:
+ - aws.ebs.gp3_50
+ volume_size_gb:
+ type: integer
+ format: int32
+ description: >-
+ The size of the storage volume, in gigabytes. Must fall within the selected
+ storage type's supported range.
+ minimum: 1
+ examples:
+ - 50
+ replicas:
+ type: integer
+ format: int32
+ description: The number of read replicas. Defaults to `0` when omitted.
+ minimum: 0
+ examples:
+ - 2
+ webpki_cert:
+ type: boolean
+ description: >-
+ Serve a publicly-trusted (WebPKI) TLS certificate rather than a Hosted-issued
+ one. Defaults to `false` when omitted.
+ examples:
+ - true
+ expose_remotesapi_endpoint:
+ type: boolean
+ description: Expose a Dolt remotes API endpoint. Defaults to `false` when omitted.
+ examples:
+ - false
+ expose_mcp:
+ type: boolean
+ description: Expose an MCP endpoint. Defaults to `false` when omitted.
+ examples:
+ - false
+ expose_stats:
+ type: boolean
+ description: Expose a statistics endpoint. Defaults to `false` when omitted.
+ examples:
+ - false
+
+ DeploymentState:
+ type: string
+ title: DeploymentState
+ description: >-
+ The deployment's lifecycle state. `starting` covers both initial provisioning and
+ a restart; poll this field to observe a create or a resize reaching `started`.
+ enum:
+ - starting
+ - started
+ - stopping
+ - stopped
+ examples:
+ - started
+
+ CloudProvider:
+ type: string
+ title: CloudProvider
+ description: The cloud the deployment runs in.
+ enum:
+ - aws
+ - gcp
+ - azure
+ examples:
+ - aws
+
+ ClusterType:
+ type: string
+ title: ClusterType
+ description: >-
+ The database engine the deployment runs. `mysql_with_dolt_replicas` is a MySQL
+ primary with Dolt read replicas.
+ enum:
+ - dolt
+ - doltgres
+ - mysql_with_dolt_replicas
+ examples:
+ - dolt
+
+ DeploymentRole:
+ type: string
+ title: DeploymentRole
+ description: >-
+ The authenticated caller's role on this deployment. Always present on a read, since
+ a caller without at least read access cannot retrieve the deployment at all.
+ enum:
+ - admin
+ - writer
+ - reader
+ - reader_and_pulls
+ examples:
+ - admin
+
+ DeploymentSummary:
+ type: object
+ title: DeploymentSummary
+ description: >-
+ A deployment as it appears in a list.
+
+
+ This is deliberately not the same shape as `Deployment`. The list RPC returns a
+ narrower record — it omits connection details, the caller's role, and the creation
+ audit fields, and it adds the last-backup figures shown in fleet views. Read the
+ deployment itself for the full resource. As with `Deployment`, database credentials
+ are never included.
+ required:
+ - owner
+ - name
+ - state
+ - cloud
+ - zone
+ - cluster_type
+ properties:
+ owner:
+ type: string
+ description: The user or organization that owns the deployment.
+ examples:
+ - acme
+ name:
+ type: string
+ description: The deployment name, unique within the owner.
+ examples:
+ - analytics
+ state:
+ $ref: "#/components/schemas/DeploymentState"
+ cloud:
+ $ref: "#/components/schemas/CloudProvider"
+ zone:
+ type: string
+ description: The cloud region the deployment runs in.
+ examples:
+ - us-west-2
+ cluster_type:
+ $ref: "#/components/schemas/ClusterType"
+ instance_type_name:
+ type: string
+ description: The display name of the deployment's instance type.
+ examples:
+ - m5.large
+ volume_type_name:
+ type: string
+ description: The display name of the deployment's storage type.
+ examples:
+ - gp3
+ volume_size_gb:
+ type: integer
+ format: int32
+ description: The size of the deployment's storage volume, in gigabytes.
+ examples:
+ - 100
+ replicas:
+ type: integer
+ format: int32
+ description: The number of read replicas. `0` for a single-instance deployment.
+ examples:
+ - 0
+ database_version:
+ type: string
+ description: >-
+ The version of the database engine the deployment is running — a Dolt version
+ for a `dolt` cluster, a Doltgres version for a `doltgres` one.
+ examples:
+ - 1.58.4
+ hourly_cost_usd:
+ type: number
+ format: float
+ description: The deployment's current cost per hour, in US dollars.
+ examples:
+ - 0.192
+ webpki_cert:
+ type: boolean
+ description: >-
+ Whether the deployment serves a publicly-trusted (WebPKI) TLS certificate.
+ examples:
+ - true
+ last_backup_size_bytes:
+ type: integer
+ format: int64
+ description: >-
+ Size of the most recent backup, in bytes. Absent when no backup has been taken
+ or its size has not been computed yet.
+ examples:
+ - 1048576
+ last_backup_time:
+ type: string
+ format: date-time
+ description: >-
+ When the most recent backup was taken. Absent when no backup has been taken.
+ examples:
+ - "2026-08-10T02:00:00Z"
+
+ Deployment:
+ type: object
+ title: Deployment
+ description: >-
+ A Hosted Dolt deployment.
+
+
+ v1 returns configuration and lifecycle state only. The deployment's database
+ credentials are deliberately **not** part of this resource — they are issued and
+ rotated through the deployment credentials endpoints, so that reading a deployment
+ is never a credential-disclosing operation.
+
+
+ Provider-specific private-networking configuration (AWS PrivateLink, GCP Private
+ Service Connect, Azure Private Link) is not included in v1.0. Each carries its own
+ endpoint collection and provisioning state, and will land as its own sub-resource;
+ adding it is additive under the stability policy.
+ required:
+ - owner
+ - name
+ - state
+ - cloud
+ - zone
+ - cluster_type
+ - caller_role
+ - created_at
+ properties:
+ owner:
+ type: string
+ description: The user or organization that owns the deployment.
+ examples:
+ - acme
+ name:
+ type: string
+ description: The deployment name, unique within the owner.
+ examples:
+ - analytics
+ state:
+ $ref: "#/components/schemas/DeploymentState"
+ cloud:
+ $ref: "#/components/schemas/CloudProvider"
+ zone:
+ type: string
+ description: The cloud region the deployment runs in.
+ examples:
+ - us-east-1
+ cluster_type:
+ $ref: "#/components/schemas/ClusterType"
+ instance_type_name:
+ type: string
+ description: >-
+ The display name of the deployment's instance type. Note this is the *name*, not
+ the id that `POST /api/v1/deployments` accepts; both are listed by the deployment
+ options endpoint.
+ examples:
+ - t2.medium
+ volume_type_name:
+ type: string
+ description: >-
+ The display name of the deployment's storage type. As with `instance_type_name`,
+ this is the name rather than the id used to create a deployment.
+ examples:
+ - Trial 50GB EBS
+ volume_size_gb:
+ type: integer
+ format: int32
+ description: The size of the deployment's storage volume, in gigabytes.
+ examples:
+ - 50
+ replicas:
+ type: integer
+ format: int32
+ description: The number of read replicas. `0` for a single-instance deployment.
+ examples:
+ - 0
+ database_version:
+ type: string
+ description: >-
+ The version of the database engine the deployment is running — a Dolt version
+ for a `dolt` cluster, a Doltgres version for a `doltgres` one.
+ examples:
+ - 1.58.4
+ host:
+ type: string
+ description: >-
+ The hostname clients connect to. Empty until the deployment reaches `started`.
+ examples:
+ - analytics.dbs.hosted.doltdb.com
+ port:
+ type: integer
+ format: int32
+ description: The port clients connect to.
+ examples:
+ - 3306
+ hourly_cost_usd:
+ type: number
+ format: float
+ description: The deployment's current cost per hour, in US dollars.
+ examples:
+ - 0.06849315
+ webpki_cert:
+ type: boolean
+ description: >-
+ Whether the deployment serves a publicly-trusted (WebPKI) TLS certificate rather
+ than a Hosted-issued one.
+ expose_remotesapi_endpoint:
+ type: boolean
+ description: Whether the deployment exposes a Dolt remotes API endpoint.
+ expose_mcp:
+ type: boolean
+ description: Whether the deployment exposes an MCP endpoint.
+ expose_stats:
+ type: boolean
+ description: Whether the deployment exposes a statistics endpoint.
+ disable_automatic_dolt_updates:
+ type: boolean
+ description: >-
+ Whether automatic Dolt version updates are disabled for this deployment.
+ caller_role:
+ $ref: "#/components/schemas/DeploymentRole"
+ created_by:
+ type: string
+ description: The username of the user who created the deployment.
+ examples:
+ - acme-ops
+ created_at:
+ type: string
+ format: date-time
+ description: When the deployment was created.
+ examples:
+ - "2026-07-01T18:22:04Z"
+ destroy_at:
+ type: string
+ format: date-time
+ description: >-
+ When the deployment is scheduled to be destroyed. Absent unless a destroy has
+ been scheduled.
+ examples:
+ - "2026-09-01T00:00:00Z"
+ destroyed_by:
+ type: string
+ description: >-
+ The username of the user who destroyed the deployment. Absent unless it has been
+ destroyed.
+ examples:
+ - acme-ops
+
+ responses:
+ BadRequest:
+ description: The request was malformed or failed input validation.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ Unauthorized:
+ description: Authentication credentials were missing or invalid.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ Forbidden:
+ description: Authenticated, but not permitted to perform this action.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ NotFound:
+ description: The requested resource does not exist.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ MethodNotAllowed:
+ description: The HTTP method is not supported for this resource.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ Allow:
+ description: The HTTP methods supported by this resource.
+ schema:
+ type: string
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ Conflict:
+ description: The request conflicts with the current state of the resource (e.g. it already exists).
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ UnprocessableEntity:
+ description: The request was well-formed but semantically invalid.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ TooManyRequests:
+ description: The client has exceeded its rate limit.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ Retry-After:
+ description: The number of seconds to wait before retrying the request.
+ schema:
+ type: integer
+ format: int32
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ InternalServerError:
+ description: An unexpected server error occurred.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"
+ ServiceUnavailable:
+ description: The service is temporarily unavailable.
+ headers:
+ x-request-id:
+ $ref: "#/components/headers/RequestId"
+ content:
+ application/problem+json:
+ schema:
+ $ref: "#/components/schemas/Problem"