Manage project delivery
import { Aside, Steps } from ‘@astrojs/starlight/components’;
The Delivery tab is where you keep the client informed about where their project is. Once you set it up, the client sees a Status page with the ETA, the ordered checkpoint list, and (optionally) a live preview URL. This guide walks the admin side.
For the client-side view and how access is granted, see Client portal.
Prerequisites
Section titled “Prerequisites”- A Melbora Website you can administer
- The Website has at least one client with access — either an owner (transferred) or a linked client (added via “Add Client”). Without one, the Delivery tab still works, but nobody’s reading it.
Set up delivery tracking
Section titled “Set up delivery tracking”Brand-new Websites have no delivery block. Until you set one up, clients see an empty Status page.
-
Open the Website in the portal and go to the Delivery tab.
If no delivery block exists yet, you’ll see a single Set up delivery tracking button.
-
Click “Set up delivery tracking”.
This calls
PUT /websites/:id/deliverywith the default body and seeds the default checkpoint template. The page reloads into the editable Delivery surface. -
Adjust the ETA.
The default ETA is 30 days from setup — almost always wrong. Set it to your actual estimated completion date.
-
Edit, add, or remove checkpoints to match the project.
The default list is intentionally generic. Customize per project.
The default checkpoint template
Section titled “The default checkpoint template”Setting up tracking seeds these six checkpoints, in this order, all
with status: "pending":
| Order | Id | Label |
|---|---|---|
| 10 | kickoff | Kickoff |
| 20 | design-approved | Design approved |
| 30 | initial-deploy | Initial deploy |
| 40 | content-loaded | Content loaded |
| 50 | qa | QA |
| 60 | launch | Launch |
You can add, rename, reorder, or delete entries per Website — the
seed is just a starting point. The order field uses ints with
gaps of 10 so you can insert new checkpoints mid-list without
renumbering everything (e.g. an order: 35 slots between
initial-deploy and content-loaded).
Checkpoint ids must be slug-ish (alphanumerics + dashes) and unique within the delivery block. A Website can have up to 40 checkpoints.
Reorder by drag
Section titled “Reorder by drag”The Delivery tab supports drag-to-reorder. Grab a checkpoint by
its burger handle and drag vertically — the motion is constrained
to the parent column so a stray horizontal drag won’t tear the row
out of the list. On drop, the portal renumbers the whole list with
the standard 10-step spacing (10, 20, 30, …) and persists the new
order ints via the same PUT /websites/:id/delivery call. There’s
no API change — the wire payload still carries the checkpoints array
in its new sequence with refreshed order values.
Set a per-checkpoint deadline
Section titled “Set a per-checkpoint deadline”Each checkpoint accepts an optional dueAt (ISO timestamp). In the
Delivery tab, click the dashed + deadline pill on any checkpoint
row to seed a default 14-days-out date and open the DatePicker
popover; the × on the pill clears it. The portal anchors the picked
date at noon UTC before sending it to the server so timezone
shifts can’t push it across a day boundary.
dueAt is display-only — no reminder emails, no status
auto-flips, no escalations. It exists so the client can see what
you’re aiming for on the Status timeline:
“Due Aug 14” on pending checkpoints, a “due …” subtext on in-progress
ones, and the completion timestamp on done ones (which supersedes
the deadline once shipped).
Update the ETA
Section titled “Update the ETA”The ETA shows up on the client’s Status page as the headline date. Bump it whenever the schedule changes — the client sees the new value on next load.
import { VantageClient } from "@vantageconnections/sdk";const vc = new VantageClient({ token: process.env.VANTAGE_TOKEN! });
const { delivery: current } = await vc.websites.delivery.get("wb_01J7XXX");
await vc.websites.delivery.update("wb_01J7XXX", { estimatedCompletionAt: "2026-07-15T00:00:00.000Z", showPreviewUrl: current?.showPreviewUrl ?? false, // Omit `checkpoints` to keep the current list; include it to replace. // Each entry may carry an optional `dueAt` (ISO; anchor it at noon UTC // to dodge timezone-shift surprises) that surfaces on the client // Status timeline. `dueAt` is display-only — no automation fires off it. checkpoints: [ { id: "kickoff", label: "Kickoff", order: 10, status: "done" }, { id: "design-approved", label: "Design approved", order: 20, status: "in_progress", dueAt: "2026-06-20T12:00:00.000Z", }, { id: "launch", label: "Launch", order: 30, status: "pending" }, ],});The update endpoint replaces the delivery block whole when
checkpoints is included; omit it to keep the existing list.
Show the preview URL to the client
Section titled “Show the preview URL to the client”showPreviewUrl defaults to false on freshly-seeded delivery
blocks. While it’s off, the client’s Status page doesn’t surface
any link to the work-in-progress site — you keep working privately.
Flip it to true when you’re comfortable with the build state and
ready to let the client poke at it.
await vc.websites.delivery.update("wb_01J7XXX", { estimatedCompletionAt: current!.estimatedCompletionAt, showPreviewUrl: true,});The URL Melbora shows the client is resolved server-side, in this order:
previewUrlOverrideif you’ve set one (see below).- The latest Vercel deployment URL for the linked Vercel project.
- Nothing — the client just won’t see a preview button this poll if neither is available (e.g. Vercel API hiccup).
Admins always see the resolved preview URL in the Delivery tab regardless of the toggle — the toggle only gates client visibility, not your own.
previewUrlOverride for custom-domain previews
Section titled “previewUrlOverride for custom-domain previews”By default Melbora resolves the preview to the latest Vercel
deployment URL (e.g. client-slug-abc123.vercel.app). If the
canonical preview lives somewhere else — a staging subdomain, a
custom domain Vercel doesn’t know about — set previewUrlOverride
to that full URL. It takes precedence over the Vercel lookup
whenever it’s non-empty.
await vc.websites.delivery.update("wb_01J7XXX", { estimatedCompletionAt: current!.estimatedCompletionAt, showPreviewUrl: true, previewUrlOverride: "https://staging.acme.com",});Set it back to "" (empty string) to clear it and fall back to
Vercel’s latest deployment.
Mark checkpoints done as you go
Section titled “Mark checkpoints done as you go”Each checkpoint has three valid statuses: pending, in_progress,
done. Flipping the status persists immediately.
// "Design approved" just shipped:await vc.websites.delivery.setCheckpointStatus( "wb_01J7XXX", "design-approved", "done");When a checkpoint flips to done, the server stamps completedAt
on the row. Flipping it out of done (back to in_progress or
pending) clears completedAt.
The 8px progress bar above the checkpoint list shows three segments
— done (solid gold), in_progress (animated diagonal stripes, the
Domino’s-tracker idiom), and pending (empty). The animation respects
prefers-reduced-motion. The sub-label adds ”· N in progress” in
gold whenever any checkpoint is mid-flight. The same bar renders on
the client Status page, so the visual treatment is intentional and
shared across both surfaces.
This corresponds to
PUT /websites/:id/delivery/checkpoints/:checkpointId
(WebsitesDeliveryApi.setCheckpointStatus
in the SDK; vantage websites delivery checkpoint in the
CLI reference).
From the CLI
Section titled “From the CLI”The same operations from a terminal:
# Read the current delivery block + resolved preview URL.vantage websites delivery get <websiteId>
# Push a new ETA (positional ISO timestamp).vantage websites delivery set-eta <websiteId> 2026-07-15T00:00:00Z
# Show / hide the preview URL to the client.vantage websites delivery set-preview <websiteId> truevantage websites delivery set-preview <websiteId> false
# Flip one checkpoint's status.vantage websites delivery checkpoint <websiteId> design-approved doneA previewUrlOverride (for surfacing a custom staging URL instead of
the latest Vercel deployment) is set via the portal’s Delivery tab or
the SDK — there’s no CLI flag for it today.
Exact subcommand listing is in the auto-generated CLI reference.
See also
Section titled “See also”- Client portal — what the client sees on the Status page and how access is granted.
- Share documents with clients — the Documents tab counterpart.
WebsitesDeliveryApireference — full SDK signatures.- REST API — auto-generated OpenAPI for the delivery routes.