The VMware Cloud Director API for Day-to-Day Operations: The Calls You Will Actually Use

    Consult Circle18 min readVMware
    The VMware Cloud Director API for Day-to-Day Operations: The Calls You Will Actually Use

    CLOUD DIRECTOR API

    A Consult Circle technical reference for provider and tenant automation: authentication, deploying from template, power operations, snapshots, disks and task handling, with notes on what changes in VCF Automation.

    Most Cloud Director automation is built from a surprisingly small set of calls. Authenticate, find something, act on it, wait for the task, check the result. Once those five things are solid, the rest is variations on a theme, and the reason automation projects stall is almost never that somebody could not find an endpoint. It is that task handling was treated as an afterthought.

    This guide covers the calls a provider or tenant actually uses day to day, with the payload shapes and the behaviour worth knowing about each. It also flags where the two APIs meet, because Cloud Director carries both the long-standing XML API and the newer JSON OpenAPI, and knowing which lives where saves a lot of searching.

    Endpoints, payload schemas and available operations vary by API version. Everything below should be validated against the API reference for the version you are actually running before it goes into production automation, and the version you request in the Accept header determines what you get.

    Two habits worth more than any endpoint reference. First, always poll the task rather than assuming a 202 means the work is done, because almost every meaningful operation is asynchronous. Second, use the query service to find objects rather than walking the object tree, because the tree traversal that works in a lab falls over on a real provider estate.

    What this guide covers

    • The two APIs, and which one to use for what
    • Authentication and session handling
    • Finding things: the query service
    • Deploying a vApp from a template
    • Power operations, and the deploy and undeploy distinction
    • Snapshots: create, revert and remove
    • Reconfiguring a VM: disks, CPU and memory
    • Catalogues, capture and cleanup
    • Task handling, error patterns and what changes in VCF Automation

    Two APIs, One Platform

    Cloud Director exposes a long-standing XML API under the /api path and a newer JSON OpenAPI under /cloudapi/1.0.0/. Both are current and neither fully replaces the other, which is confusing until you internalise the split.

    • The XML API at /api. Where the classic object model lives: vApps, VMs, virtual data centres, catalogs, and every action-style operation such as power, deploy, snapshot and reconfigure. Most day-to-day workload automation is here.
    • The OpenAPI at /cloudapi/1.0.0/. Where newer functionality lives: organisation VDC networks, roles and rights, IP spaces, edge gateway constructs, and most of what has been added over recent releases. JSON, cleaner pagination, and generally nicer to work with.
    • Version negotiation matters. The XML API is version-negotiated through the Accept header. Request a version your platform does not support and you will get an error that looks like a problem with your request rather than with your header.

    The practical rule: if the thing you are working with is a workload object, start in the XML API. If it is a networking, identity or rights object, start in the OpenAPI. If you cannot find it in one, check the other before concluding it is not exposed.

    Authentication and Sessions

    Create a session with basic authentication, then use the token it returns. On current API versions the response carries a bearer token that both APIs accept, which means one authentication serves both paths.

    # create a session (tenant user)
    curl -k -X POST \
      -u "user@org:password" \
      -H "Accept: application/*+xml;version=38.0" \
      https://vcd.example.com/api/sessions -i
    
    # provider (system) user uses the system organisation
    curl -k -X POST -u "admin@system:password" ...

    The response headers carry the access token. On recent versions this is returned as a bearer token alongside the older session header, and the bearer form is what you want for anything new. Subsequent calls carry it as an Authorization header.

    Authorization: Bearer <token>
    Accept: application/*+xml;version=38.0
    • Sessions expire on an idle timeout configured by the provider. Long-running automation should handle a 401 by re-authenticating rather than failing.
    • Do not create a session per API call. On a busy provider platform, session churn is a genuine load problem and shows up in cell performance before it shows up in your script.
    • Delete the session when your automation finishes, rather than leaving it to time out.
    • For unattended automation, use a dedicated service account with a role scoped to what it actually does, not a system administrator.

    Finding Things: The Query Service

    This is the most underused part of the API and the one that most improves automation written by people coming from the interface. Rather than walking from organisation to virtual data centre to vApp to VM, ask the query service directly.

    # all VMs visible to this session, as records
    GET /api/query?type=vm&format=records&pageSize=128
    
    # filter, and ask for only the fields you need
    GET /api/query?type=vm&filter=name==web01&fields=name,status,vdcName
    
    # provider view of VMs across all tenants
    GET /api/query?type=adminVM&format=records&pageSize=128
    • Record format returns flat records with attributes rather than full object representations, which is dramatically faster and usually sufficient.
    • The admin variants of most types give the provider view across organisations. Use them from a system session rather than iterating organisations.
    • Paginate properly. The default page size is small and results on a provider estate will be large, and a script that silently processes only the first page is a bug you will find months later.
    • Filter server-side rather than retrieving everything and filtering in your code. The difference is not subtle on a large platform.

    Deploying a vApp from a Template

    The workhorse operation. You post instantiation parameters to the target virtual data centre, referencing a vApp template from a catalogue.

    POST /api/vdc/{vdc-id}/action/instantiateVAppTemplate
    Content-Type: application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml
    
    <InstantiateVAppTemplateParams
        xmlns="http://www.vmware.com/vcloud/v1.5"
        name="web-tier-prod" deploy="true" powerOn="true">
      <Description>Deployed by automation</Description>
      <InstantiationParams>
        <NetworkConfigSection>
          <NetworkConfig networkName="app-net">
            <Configuration>
              <ParentNetwork href="https://vcd/api/network/{net-id}"/>
              <FenceMode>bridged</FenceMode>
            </Configuration>
          </NetworkConfig>
        </NetworkConfigSection>
      </InstantiationParams>
      <Source href="https://vcd/api/vAppTemplate/{template-id}"/>
    </InstantiateVAppTemplateParams>

    The response is the vApp object with a running task attached. Note the two independent flags: deploy controls whether resources are allocated in vSphere, and powerOn controls whether the workloads start. Setting powerOn without deploy is not meaningful, and setting neither creates the vApp in a stopped, undeployed state, which is often what automation actually wants before customisation.

    • Fence mode matters. Bridged attaches directly to the parent network; natRouted places the vApp behind a vApp network with its own edge, which is rarely what provider automation wants by default.
    • If the template has guest customisation configured, the workload will restart during first deployment. Account for that in any script that waits for reachability.
    • Composing a vApp from several sources uses a different action, composeVApp, which takes source items from multiple templates or existing VMs.
    • Placement failures usually surface here rather than at power on, and they usually mean storage policy or resource constraints rather than anything wrong with your payload.

    Power Operations

    Power actions exist on both vApps and individual VMs, and the same URL pattern applies to each.

    # hard operations, no payload required
    POST /api/vApp/{id}/power/action/powerOn
    POST /api/vApp/{id}/power/action/powerOff
    POST /api/vApp/{id}/power/action/reset
    POST /api/vApp/{id}/power/action/suspend
    
    # graceful guest shutdown, requires tools
    POST /api/vApp/{id}/power/action/shutdown
    POST /api/vApp/{id}/power/action/reboot

    The distinction that catches people out is between power state and deployment state. Powering off stops the workload but leaves it deployed, holding its vSphere resources. Undeploying releases those resources, and is what you want before deleting a vApp or when a tenant is genuinely finished with something.

    POST /api/vApp/{id}/action/undeploy
    Content-Type: application/vnd.vmware.vcloud.undeployVAppParams+xml
    
    <UndeployVAppParams xmlns="http://www.vmware.com/vcloud/v1.5">
      <UndeployPowerAction>shutdown</UndeployPowerAction>
    </UndeployVAppParams>

    The undeploy power action controls how the workload is stopped on the way: a graceful guest shutdown where tools are present, or a hard power off where they are not. Automation that always uses the hard option will eventually corrupt something belonging to a customer.

    Attempting a power operation that conflicts with the current state returns an error rather than being idempotent. Check state first, or handle the specific error, rather than assuming a repeated power on is harmless.

    Snapshots

    Cloud Director exposes a deliberately simple snapshot model: one snapshot per object. There is no snapshot tree, which removes a whole class of tenant-created problems and occasionally surprises people expecting vSphere behaviour.

    POST /api/vApp/{id}/action/createSnapshot
    Content-Type: application/vnd.vmware.vcloud.createSnapshotParams+xml
    
    <CreateSnapshotParams xmlns="http://www.vmware.com/vcloud/v1.5"
        name="pre-patch" memory="false" quiesce="true">
      <Description>Taken before monthly patching</Description>
    </CreateSnapshotParams>
    
    # revert to the existing snapshot
    POST /api/vApp/{id}/action/revertToCurrentSnapshot
    
    # remove all snapshots on the object
    POST /api/vApp/{id}/action/removeAllSnapshots
    • The memory flag captures memory state, which makes the snapshot considerably larger and slower. For patching workflows it is usually unnecessary.
    • Quiescing requires tools in the guest and gives a filesystem-consistent snapshot. Where tools are absent the request will not quiesce, so do not assume consistency you have not verified.
    • Because there is one snapshot per object, taking a new snapshot where one exists is not additive. Check first if your workflow assumes otherwise.
    • Snapshots are not backups and tenant-facing documentation should say so plainly. Snapshots left in place for weeks are a recurring source of storage consumption and performance complaints on provider platforms.
    • Consider an automated sweep that reports snapshots older than an agreed age. Most providers who run one find their oldest snapshot is measured in months.

    Reconfiguring a VM: Disks, CPU and Memory

    Two approaches exist. Individual hardware sections can be updated in isolation, or the whole VM can be reconfigured in a single call. For anything involving more than one change, the single call is better because it produces one task rather than several and avoids intermediate states.

    Adding a disk

    Adding a disk means retrieving the current disk section, appending an item, and putting it back. The read-modify-write pattern matters here: constructing the payload from scratch will remove disks you did not mention.

    # 1. read the current state
    GET /api/vApp/{vm-id}/virtualHardwareSection/disks
    
    # 2. append a new disk item to the returned document
    # 3. put the whole modified document back
    PUT /api/vApp/{vm-id}/virtualHardwareSection/disks
    Content-Type: application/vnd.vmware.vcloud.rasdItemsList+xml

    Disks can be grown but not shrunk. Attempting to reduce a disk size returns an error, and tenant-facing self-service should validate that before submitting rather than surfacing a raw API error to a customer.

    CPU and memory

    PUT /api/vApp/{vm-id}/virtualHardwareSection/cpu
    PUT /api/vApp/{vm-id}/virtualHardwareSection/memory

    Both require the workload to be powered off unless hot add is enabled on the template, which is a decision made when the template is built rather than at the point of the API call. If your tenants routinely resize, enabling hot add in your standard templates removes a great deal of friction.

    Reconfiguring in one call

    POST /api/vApp/{vm-id}/action/reconfigureVm
    Content-Type: application/vnd.vmware.vcloud.vm+xml
    
    # body is the full VM representation with the sections you want changed

    This takes the whole VM representation, so retrieve it first, modify what you need, and post it back. One task, one set of validations, and no window where the workload is half reconfigured.

    Guest customisation

    GET /api/vApp/{vm-id}/guestCustomizationSection
    PUT /api/vApp/{vm-id}/guestCustomizationSection

    Changing guest customisation frequently leaves the workload in a state where customisation is pending, meaning it will apply on the next power cycle. Automation that changes customisation and immediately checks the guest will see the old configuration and conclude the call failed.

    Catalogues, Capture and Cleanup

    Turning a running vApp into a template is a common provider workflow, particularly for tenant-specific golden images.

    POST /api/vdc/{vdc-id}/action/captureVApp
    Content-Type: application/vnd.vmware.vcloud.captureVAppParams+xml
    
    <CaptureVAppParams xmlns="http://www.vmware.com/vcloud/v1.5"
        name="web-golden-2026-09">
      <Source href="https://vcd/api/vApp/{vapp-id}"/>
    </CaptureVAppParams>

    Deletion has an order. A vApp must be undeployed before it can be deleted, and attempting to delete a deployed vApp returns an error that reads as a permissions problem to the uninitiated.

    POST /api/vApp/{id}/action/undeploy    # then wait for the task
    DELETE /api/vApp/{id}

    Upload workflows into catalogues go through the transfer share and are worth understanding operationally as well as programmatically, since stuck uploads are among the more common provider support tickets and they usually trace to the transfer share rather than to the API. The diagnostic sequence for those is in our guide to Cloud Director common errors and known issues.

    Task Handling, and Why It Matters More Than the Endpoints

    Nearly everything meaningful in Cloud Director is asynchronous. The call returns quickly with a task, and the work happens afterwards. Automation that treats the response as completion works perfectly in a lab and fails intermittently in production, which is the worst possible failure mode.

    GET /api/task/{task-id}
    
    # status values you will see
    #   queued | preRunning | running | success | error | canceled | aborted
    • Poll with backoff. A tight polling loop across many concurrent operations is itself a load problem on the cells. Start at a couple of seconds and back off.
    • Set a timeout, and make it operation-specific. A power on and a large template deployment do not deserve the same timeout, and a single global value will either abandon legitimate work or hang on genuinely stuck tasks.
    • Read the error detail, not just the status. A failed task carries an error element with a message and often a stack of underlying causes. The useful information is usually two levels down.
    • Handle the stuck task. Tasks can hang in running when something underlying is wrong, commonly the transfer share becoming unavailable. Your automation should be able to report a task as stuck rather than waiting indefinitely.
    • Correlate by task ID in your logs. When a tenant asks what happened at 03:12 last Tuesday, the task ID is what connects your automation log to the platform log.

    Error Patterns Worth Recognising

    SymptomUsual causeWhat to do
    401 mid-run on long automationSession idle timeout reachedRe-authenticate and retry rather than failing the run
    Error that looks like a malformed requestUnsupported API version in the Accept headerCheck the supported versions endpoint and pin deliberately
    Operation rejected due to object statevApp busy with another task, or wrong power stateCheck state, or wait for the in-flight task, before acting
    Placement failure on deploymentStorage policy or resource constraint at the targetInvestigate placement rather than the payload
    Disk change rejectedAttempting to shrink, or hot add not enabledValidate client-side before submitting
    Guest shows old configurationCustomisation pending until next power cycleExpect it, and do not treat it as a failed call
    Task hangs in runningUnderlying platform issue, often the transfer shareReport as stuck with a timeout rather than waiting forever

    Table 1 - The error patterns that account for most Cloud Director automation failures.

    Automation review

    Writing Cloud Director automation with VCFA on the roadmap?

    We review provider and tenant automation with the VCF Automation migration in view, which changes what we would advise you to write today. It is usually a short conversation.

    Explore our VMware Cloud Director services

    What Changes in VCF Automation

    If you are writing automation now and a migration to VCF Automation is on the roadmap, it is worth knowing which of this work carries forward.

    • Provider-side automation has a shorter path. Tenant Manager, the provider layer of VCF Automation, is built on the Cloud Director codebase, so the API shapes are familiar and provider automation needs rework rather than rewriting.
    • Tenant-side automation does not. The tenant experience derives from Aria Automation. Anything a customer built against the Cloud Director tenant API needs genuine rework, done by them.
    • The object model shifts. Workloads are presented through Namespaces managed by the vSphere Supervisor with assigned compute, storage classes and NSX VPCs. The vApp has no direct equivalent, so any automation built around vApps as the primary unit needs redesigning rather than porting.
    • Blocking tasks survive with narrower scope. They serve the same purpose of inserting external automation into a workflow, but are tied to provider workflows in Tenant Manager.
    • Networking objects move. Constructs that were Edge Gateways and organisation networks are expressed through VPC and Transit Gateway constructs, with firewalling through vDefend.

    The construct-level detail behind those shifts is in Mapping VMware Cloud Director constructs to VCF Automation, and what it means for the people operating the platform is covered in VCF Automation for Cloud Director administrators.

    The practical advice for anyone writing Cloud Director automation today: keep the platform-specific calls behind a thin abstraction rather than scattering them through your codebase. It costs very little now and it is the difference between a port and a rewrite later.

    Practices That Prevent Most Problems

    • One session reused across an automation run, deleted at the end, with 401 handled by re-authentication
    • API version pinned deliberately rather than inherited from an example, and validated against the platform
    • A dedicated service account with a role scoped to what the automation does
    • The query service used to find objects, with server-side filtering and correct pagination
    • Every asynchronous call followed to task completion with backoff and an operation-appropriate timeout
    • Task IDs logged so platform events can be correlated with automation runs
    • Read-modify-write used for any section update, never a payload constructed from scratch
    • Object state checked before power and lifecycle operations rather than relying on idempotency
    • Snapshot age monitored and reported, since tenants will not clean up after themselves
    • Platform calls kept behind a thin abstraction to reduce the cost of the eventual VCF Automation migration

    Frequently Asked Questions

    Should I use the XML API or the OpenAPI?

    Both, depending on the object. Workload objects such as vApps and VMs, and all the action-style operations on them, live in the XML API under /api. Networking, roles, rights and most recently added functionality live in the OpenAPI under /cloudapi/1.0.0/. If you cannot find something in one, check the other before concluding it is not exposed.

    Why does my operation return immediately but nothing happens?

    Because nearly everything in Cloud Director is asynchronous. The response gives you a task, and the work happens afterwards. Poll the task to completion and read the error detail when it fails. Automation that treats the initial response as completion works in a lab and fails intermittently in production.

    What is the difference between powering off and undeploying?

    Powering off stops the workload but leaves it deployed and holding its vSphere resources. Undeploying releases those resources. You must undeploy before deleting a vApp, and attempting to delete a deployed one returns an error that is easy to misread as a permissions problem.

    Can I take multiple snapshots of a VM?

    No. Cloud Director exposes a single snapshot per object with no snapshot tree. Taking a new one where one already exists is not additive, so any workflow assuming vSphere-style snapshot chains needs rethinking.

    Why does my disk change fail?

    The two common causes are attempting to shrink a disk, which is not supported, and attempting a change that requires the workload to be powered off where hot add was not enabled on the template. Validate both client-side rather than surfacing a raw API error to a tenant.

    How should I handle session expiry in long-running automation?

    Catch the 401, re-authenticate and retry the operation rather than failing the run. Do not work around it by creating a session per call, since session churn is a real load problem on a busy provider platform.

    Will this automation work after we migrate to VCF Automation?

    Provider-side automation has a shorter path forward because Tenant Manager inherits the Cloud Director codebase. Tenant-side automation does not, and anything built around the vApp as the primary unit needs redesigning because there is no direct equivalent. Keeping platform calls behind a thin abstraction now materially reduces that cost later.

    Where Consult Circle Fits

    We build and review provider automation against Cloud Director, and we do it with the migration to VCF Automation in view, which changes what we would advise you to write today. Automation built now without that in mind is a rewrite later rather than a port.

    We also work on the migration itself, from assessment and construct mapping through tenant execution to decommissioning, so the automation conversation and the platform conversation are the same conversation rather than two. Both sit within our VMware Cloud Director services, alongside VMware Cloud Foundation platform work where the target environment is in scope.

    Consult Circle

    Put the platform calls behind a thin abstraction

    Provider-side automation carries forward into Tenant Manager reasonably well. Automation scattered with direct vApp calls does not. We are happy to review what you have with the VCF Automation migration in mind.

    Book an automation review

    Share this article: