---
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) |
| **PATCH** | `/api/v1/deployments/{owner}/{deployment}` | [Update a deployment's settings](/products/hosted/api/v1/deployment#updateDeployment) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/instances` | [List a deployment's instances](/products/hosted/api/v1/deployment#listDeploymentInstances) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/instances` | [Add a read replica to a deployment](/products/hosted/api/v1/deployment#addDeploymentInstance) |
| **DELETE** | `/api/v1/deployments/{owner}/{deployment}/instances/{id}` | [Remove an instance from a deployment](/products/hosted/api/v1/deployment#deleteDeploymentInstance) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/instances/{id}/reboot` | [Reboot one of a deployment's instances](/products/hosted/api/v1/deployment#rebootDeploymentInstance) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/change-primary` | [Change the primary instance of a deployment](/products/hosted/api/v1/deployment#changePrimary) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/config` | [Get a deployment's configuration](/products/hosted/api/v1/deployment#getDeploymentConfig) |
| **PATCH** | `/api/v1/deployments/{owner}/{deployment}/config` | [Change some of a deployment's configuration overrides](/products/hosted/api/v1/deployment#patchDeploymentConfig) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/logs` | [Read a deployment's logs](/products/hosted/api/v1/deployment#getDeploymentLogs) |
| **PATCH** | `/api/v1/deployments/{owner}/{deployment}/expose` | [Expose or stop exposing the remotesapi or MCP endpoint](/products/hosted/api/v1/deployment#exposeDeploymentService) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/service-windows` | [List a deployment's service windows](/products/hosted/api/v1/deployment#listDeploymentServiceWindows) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/metrics` | [List a deployment's metrics](/products/hosted/api/v1/deployment#listDeploymentMetrics) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/metrics/{metric}` | [Read one of a deployment's metrics](/products/hosted/api/v1/deployment#getDeploymentMetric) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/backups` | [List a deployment's backups](/products/hosted/api/v1/deployment#listDeploymentBackups) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/backups` | [Take a backup of a deployment](/products/hosted/api/v1/deployment#createDeploymentBackup) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/database-version` | [List the versions a deployment can run](/products/hosted/api/v1/deployment#listDeploymentDatabaseVersions) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/database-version` | [Roll a deployment's database engine to another version](/products/hosted/api/v1/deployment#updateDeploymentDatabaseVersion) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/dolt-credentials` | [Read a deployment's Dolt credentials](/products/hosted/api/v1/deployment#getDeploymentDoltCredentials) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/dolt-credentials` | [Issue Dolt credentials for a deployment](/products/hosted/api/v1/deployment#createDeploymentDoltCredentials) |
| **DELETE** | `/api/v1/deployments/{owner}/{deployment}/dolt-credentials` | [Remove a deployment's Dolt credentials](/products/hosted/api/v1/deployment#deleteDeploymentDoltCredentials) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/dolt-credentials/reroll` | [Replace a deployment's Dolt credentials](/products/hosted/api/v1/deployment#rerollDeploymentDoltCredentials) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/disable` | [Disable a deployment](/products/hosted/api/v1/deployment#disableDeployment) |

### Pull request

| Method | Path | What it does |
|--------|------|--------------|
| **GET** | `/api/v1/deployments/{owner}/{deployment}/pulls` | [List a database's pull requests](/products/hosted/api/v1/pull-request#listDeploymentPulls) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/pulls/{id}/comments` | [List a pull request's comments](/products/hosted/api/v1/pull-request#listDeploymentPullComments) |
| **POST** | `/api/v1/deployments/{owner}/{deployment}/pulls/{id}/comments` | [Comment on a pull request](/products/hosted/api/v1/pull-request#createDeploymentPullComment) |
| **GET** | `/api/v1/deployments/{owner}/{deployment}/pulls/{id}/logs` | [List a pull request's activity log](/products/hosted/api/v1/pull-request#listDeploymentPullLogs) |

### Operation

| Method | Path | What it does |
|--------|------|--------------|
| **GET** | `/api/v1/operations/{id}` | [Get the status of queued work](/products/hosted/api/v1/operation#getOperation) |

## 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. Page size is fixed and not caller-controlled, so a full page is not itself a sign that another one follows.

Two kinds of list depart from that. A pull request's [comments](/products/hosted/api/v1/pull-request#listDeploymentPullComments) and its [activity log](/products/hosted/api/v1/pull-request#listDeploymentPullLogs), and a deployment's [metrics catalogue](/products/hosted/api/v1/deployment#listDeploymentMetrics) and [service windows](/products/hosted/api/v1/deployment#listDeploymentServiceWindows), are small enough by nature to be returned whole, so they take no `page_token` at all. And [log retrieval](/products/hosted/api/v1/deployment#getDeploymentLogs) walks a window of history rather than a finite list: it is the only endpoint that pages in both directions, and the only one whose page size you set (`lines`). There `meta.next_page_token` reads further back, `meta.prev_page_token` reads toward the present, both can be present at once, and either can come back on a page with no lines — so stop when a page comes back empty, not when a token is missing.

Each endpoint's parameters say which of the three it is.

## 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`.

[Disabling a deployment](/products/hosted/api/v1/deployment#disableDeployment) works the same way: `202 Accepted` with the deployment in `stopping`, then poll until `state` is `stopped`.

Instance changes are also `202`, and are followed through the [instance list](/products/hosted/api/v1/deployment#listDeploymentInstances), where each instance reports its own `state`. After [adding a replica](/products/hosted/api/v1/deployment#addDeploymentInstance), poll until that instance reports `state: started` and a `host` — both together are what make it reachable, since a `started` instance has an address to connect to. After [removing one](/products/hosted/api/v1/deployment#deleteDeploymentInstance), poll until it leaves the list, which reports only instances that aren't stopped; while it is still there, `state: stopping` distinguishes it from one still running.

[Exposing or unexposing a service](/products/hosted/api/v1/deployment#exposeDeploymentService) is `202` too, and is polled on the deployment itself: read it back until `expose_remotesapi_endpoint` or `expose_mcp` reports the value you asked for, which is written once the change reaches the instances. The `202` body echoes the request rather than the deployment's current state. Exposing the remotesapi endpoint needs a WebPKI certificate — `webpki_cert` on the deployment says whether it has one, and without it the request is a `400` rather than a queued change.

[Taking a backup](/products/hosted/api/v1/deployment#createDeploymentBackup), [rolling the database version](/products/hosted/api/v1/deployment#updateDeploymentDatabaseVersion), and [rebooting an instance](/products/hosted/api/v1/deployment#rebootDeploymentInstance) return `202` with an [OperationRef](/products/hosted/api/v1/models#model-operationref). Follow its `href`, or pass its `id` to [Get an operation](/products/hosted/api/v1/operation#getOperation), and poll with a delay until `status` is `succeeded` or `failed`. Completion means different things for each action: a version roll waits for every instance to report the requested version, backup completion is inferred from successful backup timestamps, and a reboot succeeds when the platform accepts the request, before the database is necessarily ready. A failed operation does not imply rollback, and a transient HTTP error while polling is not a reason to submit the action again.

[Issuing](/products/hosted/api/v1/deployment#createDeploymentDoltCredentials), [removing](/products/hosted/api/v1/deployment#deleteDeploymentDoltCredentials), or [replacing Dolt credentials](/products/hosted/api/v1/deployment#rerollDeploymentDoltCredentials) also returns `202` with an OperationRef to poll. These credentials let the deployment access private databases on DoltHub. After issuing or replacing them succeeds, [read the public key](/products/hosted/api/v1/deployment#getDeploymentDoltCredentials) and add it to the appropriate DoltHub account. After removal succeeds, that read returns `404`. Replacement can temporarily leave instances with different credentials, and a failed operation does not roll back changes.

[Changing the primary](/products/hosted/api/v1/deployment#changePrimary) returns `202` with an OperationRef as well, and needs admin on the deployment. Send the id of the instance the list currently shows as primary: Hosted checks it is still the primary before accepting, so a request built from a stale read is rejected rather than allowed to undo a newer change. Hosted picks the replacement from the replicas, which is why the operation reaching `succeeded` tells you the switch happened but not what it landed on — read the [instance list](/products/hosted/api/v1/deployment#listDeploymentInstances) to see which instance is primary now.

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.** Disabling one tears down its instances and their storage — [take a backup first](/products/hosted/api/v1/deployment#createDeploymentBackup) and confirm completion if you want the data.

## 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.
