# Every API endpoint

> The complete list of veldhost API endpoints, generated from the live OpenAPI document, grouped by area.

Source: https://veldhost.eu/docs/api-endpoints

Last verified: 2026-11-13

This page lists every endpoint of the veldhost API, version 1.6. It is generated from the same OpenAPI document the API serves at `https://manage.veldhost.eu/api/v1/openapi.json`, so it always matches what the API actually accepts.

All paths are relative to `https://manage.veldhost.eu/api/v1`. Every request needs a personal API token (or an assistant's access token) in the `Authorization: Bearer …` header; see [API tokens and authentication](https://veldhost.eu/docs/api-authentication). Endpoints marked **Idempotency-Key** accept that header, so a retried request is safe; see [Errors, rate limits and idempotency](https://veldhost.eu/docs/api-errors-and-limits).

For request and response fields, load the OpenAPI document into any OpenAPI tool, or read the [API reference](https://veldhost.eu/docs/api-reference) for the main workflows.

## Sites

Hosted sites: state, deploys, logs, health, usage.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/sites` | List your sites |  |
| `POST` | `/sites` | Quote a new site (returns a portal continuation URL — never creates or charges) |  |
| `POST` | `/sites/{slug}/deploy` | Deploy from the configured git repository (deploy scope) | Yes |
| `GET` | `/sites/{slug}/deploys` | Deploy history, newest first |  |
| `GET` | `/sites/{slug}/logs` | Recent log lines (tail of the file, up to 200), plus the same lines folded into timed entries |  |
| `GET` | `/sites/{slug}/health` | Live health + open incidents (works on non-active sites too) |  |
| `GET` | `/sites/{slug}/traffic` | Disk + network usage (billing-period traffic when available) |  |
| `GET` | `/sites/{slug}/analytics` | Request analytics: hourly/daily series + 24h/7d/30d rollups (requests, visitors, status codes, top pages) |  |

## Site settings

A site's runtime, build steps, environment variables, redirects and domains.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/sites/{slug}/settings` | PHP/Node.js version and choices, start command, build steps and deploy trigger, domain and its state, extra domains (domain, mode, state), a Laravel site's queue worker, environment variable names (secret values never shown) |  |
| `PUT` | `/sites/{slug}/env/{key}` | Create or replace a runtime environment variable (manage scope); applies within a minute | Yes |
| `DELETE` | `/sites/{slug}/env/{key}` | Remove a runtime environment variable (manage scope) | Yes |
| `PATCH` | `/sites/{slug}/runtime` | Switch PHP version, Node.js version or start command (manage scope) | Yes |
| `PATCH` | `/sites/{slug}/build` | Build steps and deploy trigger for the next git deploy (deploy scope) | Yes |
| `PATCH` | `/sites/{slug}/queue-worker` | A Laravel site's always-on queue worker (manage scope): enabled, workers (1 up to the plan's max_workers in settings.queue_worker), connection (database; needs the site's database). Applied within a minute; workers restart on every deploy | Yes |
| `POST` | `/sites/{slug}/redirects` | Add a permanent (301) redirect from a path on the site to a path or an http(s) address (manage scope); at most 20 per site | Yes |
| `DELETE` | `/sites/{slug}/redirects` | Remove the redirect for one path (manage scope) | Yes |
| `POST` | `/sites/{slug}/domain` | Connect a custom domain (manage scope): connected with next steps, or needs_portal + continue_url when its email must be carried across first. A site that already has a domain keeps it and gets this one as an extra domain: mode redirect (default) or serve | Yes |

## Releases

CI/CD releases: approve one awaiting approval, discard it, or roll back to an earlier one.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `POST` | `/sites/{slug}/deploys/{id}/approve` | Publish a CI/CD release awaiting approval (deploy scope) | Yes |
| `POST` | `/sites/{slug}/deploys/{id}/discard` | Discard a release awaiting approval; the live site is untouched (deploy scope) | Yes |
| `POST` | `/sites/{slug}/deploys/{id}/rollback` | Return the files to an earlier release the host still has; the database is not changed (deploy scope) | Yes |

## Backups

Restore points and staging copies.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/sites/{slug}/backups` | List backups, newest first |  |
| `POST` | `/sites/{slug}/backups` | Back up now (manage scope) | Yes |
| `POST` | `/sites/{slug}/restore` | Restore a backup over the live site (replaces current content; manage scope) | Yes |
| `GET` | `/sites/{slug}/staging` | Staging status |  |
| `POST` | `/sites/{slug}/staging` | Create / refresh / turn off the staging copy (owner-only; billed on plans without staging included; manage scope) | Yes |

## Cron

Scheduled tasks (PHP runtimes).

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/sites/{slug}/cron` | List scheduled tasks |  |
| `POST` | `/sites/{slug}/cron` | Add a scheduled task (php/wp commands only, max 5; manage scope) | Yes |
| `DELETE` | `/sites/{slug}/cron/{index}` | Remove a scheduled task by index (manage scope) | Yes |

## Domains

Registered domains and the registry.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/domains` | List domains registered on your account |  |
| `GET` | `/domains/search` | Domain availability + yearly price (read-only). veldhost does not sell registrations self-serve: offered=false means bring your own domain or ask support |  |
| `GET` | `/domains/{domain}` | One registered domain |  |
| `GET` | `/domains/{domain}/registrar` | Registrar state: registry vs live nameservers, DNSSEC comparison, lock, WHOIS privacy |  |
| `PUT` | `/domains/{domain}/nameservers` | Change the delegation (dns scope). Same rules as the portal. 409 (with reason) while a transfer is pending; 409 with continue_url while DNSSEC is active or its DS waiting period (safe_at) runs — that move needs a human | Yes |
| `POST` | `/domains/{domain}/dnssec` | Registered with us: sign the zone and publish its DS at the registry (dns scope). An assistant connection (OAuth or MCP) is asked twice: 409 needs_confirmation with confirm_token first; a personal API token acts on the first call. 403 while DNSSEC is not self-serve for customers (ask us); 409 with continue_url when the zone is not hosted here or the registry holds a DS that is not ours. Registered elsewhere, zone hosted here: signs the zone and returns the DS (ds, ds_records with the DNSKEY fields) to add at your own registrar, status signed (or dnssec_active once the parent DS matches); nothing is published, so it is never asked twice. 404 when the account has neither the domain nor its zone | Yes |

## DNS

Authoritative DNS zones and records.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/dns` | List your DNS zones |  |
| `POST` | `/dns/zones/probe` | Probe the live public zone of a domain you are moving to veldhost DNS (dns scope). Dry-run only: returns the records public resolvers answer for it as an import plan (adds/updates/unchanged/skipped/rejected with reasons), the current nameservers, whether DNSSEC is on at the current provider, the registrar detected via RDAP with nameserver instructions, and a continue_url where the human creates the zone. Never writes, never touches the registrar |  |
| `GET` | `/dns/{zone}/records` | List zone records (system/DNSSEC records hidden) |  |
| `POST` | `/dns/{zone}/records` | Add a record (live in under a second; dns scope) | Yes |
| `PUT` | `/dns/{zone}/records/{record}` | Update a record (dns scope) | Yes |
| `DELETE` | `/dns/{zone}/records/{record}` | Delete a record (dns scope) | Yes |
| `GET` | `/dns/{zone}/export` | Export the zone as a BIND master file (text/plain; SOA and apex NS as comments) |  |
| `POST` | `/dns/{zone}/import` | Import a BIND zone file (dns scope). dry_run=true (default) only returns the plan; false applies adds/updates through the same rules as the editor and never deletes | Yes |

## Email

Domains with veldhost email: their mailboxes, verification and the DNS records they still need.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/mail` | Domains with veldhost email and their mailboxes (read scope) |  |
| `GET` | `/mail/{domain}` | One email domain: its mailboxes, verification and the DNS records it still needs |  |
| `POST` | `/mail/{domain}/verify` | Check the verification record now (dns scope); veldhost also checks every 15 minutes | Yes |

## Data

Databases: your site databases (MariaDB and PostgreSQL) and warehouse databases, their schema, read-only SQL on sites and writes on the warehouse. Needs the opt-in data scope.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/data/databases` | Your site databases with engine, state and what the token may do (data scope; narrowed by the token's sites) |  |
| `GET` | `/data/databases/{id}/schema` | Tables, views and columns of one database (data scope). The first call prepares the read-only login and introspects: it answers 202 with state "preparing" — poll again after a few seconds |  |
| `POST` | `/data/query` | Run ONE statement and wait up to wait_s for it (data scope). Site databases: read-only (SELECT, WITH, SHOW, EXPLAIN, DESCRIBE, VALUES); writes, DDL, locks, multiple statements and sleep/file functions are refused with 422 sql_rejected before anything is queued. Warehouse databases with mode rw: also INSERT/UPDATE/DELETE and CREATE/ALTER/DROP TABLE, VIEW, INDEX, TRUNCATE, plus REPLACE and RENAME TABLE on MariaDB only (PostgreSQL: INSERT … ON CONFLICT, ALTER TABLE … RENAME TO) (60 s ceiling); a destructive statement answers 422 needs_confirmation with summary/kind/table until sent again with confirmed: true. Rows are capped at limit (max 1,000) and 30 s | Yes |
| `POST` | `/data/warehouse/databases` | Create a database in your warehouse (data scope; not for tokens limited to particular sites). The first database also creates the warehouse container (about a minute); the database is pending until the host created it, then active in /data/databases |  |
| `DELETE` | `/data/warehouse/databases/{id}` | Drop a warehouse database and its writer login (data scope; owner, admin or developer). Refused with 409 while a statement is still running on it |  |
| `GET` | `/data/runs/{id}` | One query run: status, rows once succeeded, or the error (data scope) |  |

## Dashboards

Dashboards: grids of charts, stats and tables over your databases, with a time range, auto-refresh and variables. Panel SQL may use the dashboard macros ($__timeFilter, $__timeGroupAlias, $__interval, ${variable}); the server expands them and answers from a short-lived cache. Needs the opt-in data scope.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/dashboards` | Your dashboards, every one on your accounts (data scope) |  |
| `POST` | `/dashboards` | Create a dashboard, optionally with panels and variables (data scope; owner, admin or developer on an account with an active plan). Panel SQL is read-only and may use the macros $__timeFilter(col), $__timeFrom(), $__timeTo(), $__unixEpochFilter(col), $__unixEpochFrom(), $__unixEpochTo(), $__interval, $__interval_s, $__range_s, $__timeGroup(col[, iv]), $__timeGroupAlias(col[, iv]) and ${variable} | Yes |
| `GET` | `/dashboards/{uid}` | One dashboard: its model with every panel (sql only where the token may query that database) |  |
| `PUT` | `/dashboards/{uid}` | Replace the whole model (send the version you read; 409 stale_version when it moved on). A panel keeps its editor unless its SQL or database changed | Yes |
| `DELETE` | `/dashboards/{uid}` | Delete a dashboard (author, or account owner/admin) | Yes |
| `POST` | `/dashboards/{uid}/panels` | Add one panel, below the others unless grid is given | Yes |
| `PUT` | `/dashboards/{uid}/panels/{key}` | Change one panel; fields not sent keep their value | Yes |
| `DELETE` | `/dashboards/{uid}/panels/{key}` | Remove one panel | Yes |
| `POST` | `/dashboards/{uid}/panels/{key}/data` | The rows behind one panel for a time range: answered from the cache when an identical run is fresh, otherwise a new run with a wait of up to wait_s (data scope; any member of the account). The resolved SQL and the engine error text only when the token may query the panel's database |  |

## Pipelines

Pipelines: SQL that builds tables in one of your warehouse databases. Databases are named in the SQL by the name /data/databases shows (shop.orders, or shop.public.orders on PostgreSQL). Two statement forms — CREATE OR REFRESH TABLE [<warehouse>.]<name> [KEY (cols)] AS <select>, built in the warehouse (KEY upserts, no KEY rebuilds), which may read site tables as <database>.<table>; and CREATE OR REFRESH SOURCE VIEW <name> [FROM <database>] AS <select>, which runs on the site database in its own dialect and stages only the rows it selects. The order tables are built in is derived from the SQL: every name after FROM or JOIN. Compiling is free and answers with a file and a line per problem. Needs the opt-in data scope.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/pipelines` | Your pipelines, every one on your accounts (data scope) |  |
| `POST` | `/pipelines` | Create a pipeline (data scope; owner, admin or developer on an account with an active plan). Every database it names is checked against YOU now and against its author each time it runs. The answer carries `compile`, so read it before telling anyone it works | Yes |
| `GET` | `/pipelines/{id}` | One pipeline: its SQL files, its sources, the derived graph and how the last run went |  |
| `PUT` | `/pipelines/{id}` | Replace the whole document (send the version you read; 409 stale_version when it moved on). Saving makes you the author, and therefore the authority its runs act with. A pipeline whose SQL does not compile still saves — `compile.ok` says so | Yes |
| `DELETE` | `/pipelines/{id}` | Delete a pipeline and its run history (author, or account owner/admin). The tables it built stay in your warehouse | Yes |
| `POST` | `/pipelines/{id}/compile` | What the SQL means, without running it: every problem with its file and line, the dependency graph, the build order and the plan. Reads nothing and writes nothing, so iterate here rather than on a run |  |
| `POST` | `/pipelines/{id}/preview` | Try it on a sample without writing anything: a couple of hundred rows per source view into throwaway tables, each table built into a temporary one, a sample of the rows back, everything dropped again | Yes |
| `POST` | `/pipelines/{id}/run` | Build every table now. One run per account at a time: a pipeline asked for while something else is running answers with a run whose status is skipped | Yes |
| `GET` | `/pipelines/{id}/runs` | This pipeline's run history, newest first |  |

## Jobs

Jobs: an ordered list of steps we run for you — SQL on a warehouse database, refreshing a dashboard, emailing a report, calling one of your webhooks, waiting, or starting another job — on a cron schedule in your own time zone, after another job, or when you ask. Needs the opt-in data scope.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/jobs` | Your jobs, every one on your accounts (data scope) |  |
| `POST` | `/jobs` | Create a job (data scope; owner, admin or developer on an account with an active plan). Every database a step names is checked against YOU now and against the job's author each time it runs | Yes |
| `GET` | `/jobs/{id}` | One job: its trigger, steps, budget and last run |  |
| `PUT` | `/jobs/{id}` | Replace the whole model (send the version you read; 409 stale_version when it moved on). Saving makes you the job's author, and therefore the authority its scheduled runs act with | Yes |
| `DELETE` | `/jobs/{id}` | Delete a job and its run history (author, or account owner/admin) | Yes |
| `POST` | `/jobs/{id}/run` | Run this job now. One run per account at a time: a job that is already running answers with a run whose status is skipped (concurrency skip) or queued (concurrency queue). When the account's monthly spend cap on job minutes is reached the call is refused with 422 error type usage_cap and a billing_url | Yes |
| `GET` | `/jobs/{id}/runs` | This job's run history, newest first |  |
| `GET` | `/jobs/runs` | Every run on your accounts, newest first — jobs and pipelines in one view |  |
| `GET` | `/jobs/runs/{id}` | One run and its steps, optionally after waiting up to wait_s for it to settle (200 settled, 202 still going) |  |
| `POST` | `/jobs/runs/{id}/cancel` | Ask a run to stop. A queued run stops at once; a running one stops between steps, never mid-statement | Yes |

## Webhooks

Outbound webhooks and chat channels.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/webhooks` | List your outbound webhooks (manage scope) |  |
| `POST` | `/webhooks` | Add an outbound webhook. The signing secret is returned ONCE in this response | Yes |
| `DELETE` | `/webhooks/{id}` | Delete an outbound webhook | Yes |
| `POST` | `/webhooks/{id}/test` | Queue a webhook.test delivery to this endpoint | Yes |

## Account

Your own audit trail and invoices.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/account/audit` | Your own audit trail: sign-ins, security changes, purchases, portal actions and API writes, newest first (read scope) |  |
| `GET` | `/account/invoices` | Issued invoices for your account, newest first — the same list the billing page shows (read scope) |  |
| `GET` | `/signup` | For an assistant helping someone WITHOUT an account: plans, prices and a pre-filled sign-up link the person opens and completes themselves. Public (no token), creates and sends nothing |  |
| `GET` | `/account/team` | Members and their roles, and pending invites (read scope; changing the team is done in the portal) |  |

## Orders

Orders an assistant or script proposes for an owner or billing member to approve. Nothing is bought without that approval. Needs the billing scope.

| Method | Path | What it does | Idempotency-Key |
| --- | --- | --- | --- |
| `GET` | `/orders` | Orders proposed on this account and their state (billing scope) |  |
| `POST` | `/orders` | Propose an order for the customer to approve (billing scope). Nothing is bought: owners and billing members are emailed and approve at approve_url | Yes |
| `GET` | `/orders/{order}` | One order: state, price, approve_url and, once approved, where it led (billing scope) |  |
| `DELETE` | `/orders/{order}` | Withdraw an order still awaiting approval (billing scope) | Yes |

## Related

- [API reference](https://veldhost.eu/docs/api-reference)
- [Scopes and permissions for tokens and assistants](https://veldhost.eu/docs/scopes-and-permissions)
- [MCP tool reference](https://veldhost.eu/docs/mcp-tools)