# Deploy API

 

This is the API specification and some examples for the HTTP Deploy API that can be used to deploy an application:

- [upload](#create-session)
- [prepare](#prepare-session)
- [activate](#activate-session)

The response format is JSON. Examples are found in the [use-cases](#use-cases). Also see the [deploy guide](/en/basics/applications.html#deploying-applications).

 **Note:** To build a multi-application system, use one or three config server(s) per application. Best practise is using a [containerized](/en/operations/self-managed/docker-containers.html) architecture, also see [multinode-HA](https://github.com/vespa-engine/sample-apps/tree/master/examples/operations/multinode-HA).

The current API version is 2. The API port is 19071 - use [vespa-model-inspect](/en/reference/operations/self-managed/tools.html#vespa-model-inspect) service configserver to find config server hosts. Example: `http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session`. Write operations return successfully after a majority of config servers have persisted changes (e.g. 2 out of 3 config servers).

Entities:

| session-id | 

The session-id used in this API is generated by the server and is required for all operations after [creating](#create-session) a session. The session-id is valid if it is an active session, or it was created before [session lifetime](https://github.com/vespa-engine/vespa/blob/master/configdefinitions/src/vespa/configserver.def) has expired, the default value being 1 hour.

 |
| path | 

An application file path in a request URL or parameter refers to a relative path in the application package. A path ending with "/" refers to a directory.

 |

Use [Vespa CLI](../../clients/vespa-cli.html) to deploy from the command line.

## POST /application/v2/tenant/default/prepareandactivate

Creates a new session with the application package that is included in the request, prepares it and then activates it. See details in the steps later in this document

| Parameters | 

| Name | Default | Description |
| --- | --- | --- |
| | | |

 |
| Request body | 

| Required | Content | Note |
| --- | --- | --- |
| Yes | A compressed [application package](../applications/application-packages.html) (with gzip or zip compression) | Set `Content-Type` HTTP header to `application/x-gzip` or `application/zip`. |

 |
| Response | 

See [active](#activate-session).

 |

Example:

```
$ (cd src/main/application && zip -r - .) | \
  curl --header Content-Type:application/zip --data-binary @- \
  localhost:19071/application/v2/tenant/default/prepareandactivate
```

```
```
{
    "log": [
        {
            "time": 1619448107299,
            "level": "WARNING",
            "message": "Host named 'vespa-container' may not receive any config since it is not a canonical hostname. Disregard this warning when testing in a Docker container."
        }
    ],
    "tenant": "default",
    "session-id": "3",
    "url": "http://localhost:19071/application/v2/tenant/default/application/default/environment/prod/region/default/instance/default",
    "message": "Session 3 for tenant 'default' prepared and activated.",
    "configChangeActions": {
        "restart": [],
        "refeed": [],
        "reindex": []
    }
}
```
```

## POST /application/v2/tenant/default/session

Creates a new session with the application package that is included in the request.

| Parameters | 

| Name | Default | Description |
| --- | --- | --- |
| from | N/A | Use when you want to create a new session based on an active application. The value supplied should be a URL to an active application. |

 |
| Request body | 

| Required | Content | Note |
| --- | --- | --- |
| Yes, unless `from` parameter is used | A compressed [application package](../applications/application-packages.html) (with gzip or zip compression) | It is required to set the `Content-Type` HTTP header to `application/x-gzip` or `application/zip`, unless the `from` parameter is used. |

 |
| Response | The response contains: 
- A [session-id](#session-id) to the application that was created.
- A [prepared](#prepare-session) URL for preparing the application.

 |

Examples (both requests return the same response):

- `POST /application/v2/tenant/default/session`
- `POST /application/v2/tenant/default/session?from=http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/application/default/environment/default/region/default/instance/default`

```
{
    "tenant": "default",
    "session-id": "1",
    "prepared": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/session-id/prepared/",
    "content": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/session-id/content/",
    "message": "Session 1 for tenant 'default' created."
}
```

## PUT /application/v2/tenant/default/session/[[session-id](#session-id)]/content/[[path](#path)]

Writes the content to the given path, or creates a directory if the path ends with '/'.

| Parameters | None |
| Request body | 

- If path is a directory, none.
- If path is a file, the contents of the file.

 |
| Response | 

None

- Any errors or warnings from writing the file/creating the directory.

 |

## GET /application/v2/tenant/default/session/[[session-id](#session-id)]/content/[[path](#path)]

Returns the content of the file at this path, or lists files and directories if `path` ends with '/'.

| Parameters | 

| Name | Default | Description |
| --- | --- | --- |
| recursive | false | If _true_, directory content will be listed recursively. |
| return | content | 
- If set to content and path refers to a file, the content will be returned.
- If set to content and path refers to a directory, the files and subdirectories in the directory will be listed.
- If set to status and path refers to a file, the file status and hash will be returned.
- If set to status and path refers to a directory, a list of file/subdirectory statuses and hashes will be returned.

 |

 |
| Request body | None. |
| Response | 

- If path is a directory: a JSON array of URLs to the files and subdirectories of that directory.
- If path is a file: the contents of the file.
- If status parameter is set, the status and hash will be returned.

 |

Examples:

`GET /application/v2/tenant/default/session/3/content/`

```
```
[
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/hosts.xml",
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/services.xml",
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/"
]
```
```

`GET /application/v2/tenant/default/session/3/content/?recursive=true`

```
```
[
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/hosts.xml",
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/services.xml",
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/",
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/music.sd",
    "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/video.sd"
]
```
```

`GET /application/v2/tenant/default/session/3/content/hosts.xml`

```
```
<?xml version="1.0" encoding="utf-8" ?>
<hosts>
    <host name="myhost.mydomain.com">
        <alias>vespa1</alias>
    </host>
    <host name="myhost.mydomain.com">
        <alias>vespa2</alias>
    </host>
</hosts>
```
```

`GET /application/v2/tenant/default/session/3/content/hosts.xml?return=status`

```
```
{
    "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/hosts.xml",
    "status": "new",
    "md5": "03d7cff861fcc2d88db70b7857d4d452"
}
```
```

`GET /application/v2/tenant/default/session/3/content/schemas/?return=status`

```
```
[
    {
        "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/music.sd",
        "status": "new",
        "md5": "03d7cff861fcc2d88db70b7857d4d452"
    },
    {
        "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/video.sd",
        "status": "changed",
        "md5": "03d7cff861fcc2d88db70b7857d4d452"
    },
    {
        "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/content/schemas/book.sd",
        "status": "deleted",
        "md5": "03d7cff861fcc2d88db70b7857d4d452"
    }
]
```
```

## DELETE /application/v2/tenant/default/session/[[session-id](#session-id)]/content/[[path](#path)]

Deletes the resource at the given path.

| Parameters | None |
| Request body | 

None

 |
| Response | 

Any errors or warnings from deleting the resource.

 |

## PUT /application/v2/tenant/default/session/[[session-id](#session-id)]/prepared

Prepares an application with the [session-id](#session-id) given.

| Parameters | 

| Parameter | Default | Description |
| --- | --- | --- |
| applicationName | N/A | Name of the application to be deployed |
| environment | default | Environment where application should be deployed |
| region | default | Region where application should be deployed |
| instance | default | Name of application instance |
| debug | false | If true, include stack trace in response if prepare fails. |
| timeout | 360 seconds | Timeout in seconds to wait for session to be prepared. |

 |
| Request body | 

None

 |
| Response | 

Returns a [session-id](#session-id) and a link to activate the session.

- Log with any errors or warnings from preparing the application.
- An [activate](#activate-session) URL for activating the application with this [session-id](#session-id), if there were no errors.
- A list of actions (possibly empty) that must be performed in order to apply some config changes between the current active application and this next prepared application. These actions are organized into three categories; _restart_, _reindex_, and _refeed_: 
  - _Restart_ actions are done after the application has been activated and are handled by restarting all listed services. See [schemas](../schemas/schemas.html#modifying-schemas) for details.
  - _Reindex_ actions are special refeed actions that Vespa [handles automatically](../../operations/reindexing.html), if the [reindex](#reindex) endpoint below is used.
  - _Refeed_ actions require several steps to handle. See [schemas](../schemas/schemas.html#modifying-schemas) for details.

 |

Example:

`PUT /application/v2/tenant/default/session/3/prepared`

```
```
{
    "tenant": "default",
    "session-id": "3",
    "activate": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/session/3/active",
    "message": "Session 3 for tenant 'default' prepared.",
    "log": [
           { "level": "WARNING",
             "message": "Warning message 1",
             "time": 1430134091319
           },
           { "level": "WARNING",
             "message": "Warning message 2",
             "time": 1430134091320
           }
        ],
    "configChangeActions": {
        "restart": [ {
            "clusterName": "mycluster",
            "clusterType": "search",
            "serviceType": "searchnode",
            "messages": ["Document type 'test': Field 'f1' changed: add attribute aspect"],
            "services": [ {
                "serviceName": "searchnode",
                "serviceType": "searchnode",
                "configId": "mycluster/search/cluster.mycluster/0",
                "hostName": "myhost.mydomain.com"
            } ]
        } ],
        "reindex": [ {
            "documentType": "test",
            "clusterName": "mycluster",
            "messages": ["Document type 'test': Field 'f1' changed: add index aspect"],
            "services": [ {
                "serviceName": "searchnode",
                "serviceType": "searchnode",
                "configId": "mycluster/search/cluster.mycluster/0",
                "hostName": "myhost.mydomain.com"
            } ]
        } ]
    }
}
```
```

## GET /application/v2/tenant/default/session/[[session-id](#session-id)]/prepared

Returns the state of a prepared session. The response is the same as a successful [prepare](#prepare-session) operation (above), however the _configChangeActions_ element will be empty.

## PUT /application/v2/tenant/default/session/[[session-id](#session-id)]/active

Activates an application with the [session-id](#session-id) given. The [session-id](#session-id) must be for a [prepared session](#prepare-session). The operation will make sure the session is activated on all config servers.

| Parameters | 

| Parameter | Default | Description |
| --- | --- | --- |
| timeout | 60 seconds | Timeout in seconds to wait for session to be activated (when several config servers are used, they might need to sync before activate can be done). |

 |
| Request body | None |
| Response | 

Returns a [session-id](#session-id), a message and a URL to the activated application.

- [session-id](#session-id)
- Message

 |

Example:

`PUT /application/v2/tenant/default/session/3/active`

```
```
{
    "tenant": "default",
    "session-id": "3",
    "message": "Session 3 for tenant 'default' activated.",
    "url": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/application/default/environment/default/region/default/instance/default"
}
```
```

## GET /application/v2/tenant/default/application/

Returns a list of the currently active applications for the given tenant.

| Parameters | None |
| Request body | None |
| Response | 

Returns a list of applications

- Array of active applications

 |

Example:

`GET /application/v2/tenant/default/application/`

```
```
{
    ["http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/application/default/environment/default/region/default/instance/default"]
}
```
```

## GET /application/v2/tenant/default/application/default

Gets info about the application.

| Parameters | None |
| Request body | None |
| Response | 

Returns information about the application specified.

- config generation

 |

Example:

`GET /application/v2/tenant/default/application/default`

```
```
{
    "generation": 2
}
```
```

## GET /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindexing

Returns [reindexing](../../operations/reindexing.html) status for the given application.

| Parameters | N/A |
| Request body | N/A |
| Response | JSON detailing current reindexing status for the application, with all its clusters and document types. 
- Status for each content cluster in the application, by name: 
  - Status of each document type in the cluster, by name: 
    - Last time reindexing was triggered for this document type.
    - Current status of reindexing.
    - Optional start time of reindexing.
    - Optional end time of reindexing.
    - Optional progress of reindexing, from 0 to 1.
    - Pseudo-speed of reindexing.

 |

Example:

`GET /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindexing`

```
```
{
    "clusters": {
        "db": {
            "ready": {
                "test_artifact": {
                    "readyMillis": 1607937250998,
                    "startedMillis": 1607940060012,
                    "state": "running",
                    "speed": 1.0,
                    "progress": 0.04013824462890625
                },
                "test_result": {
                    "readyMillis": 1607688477294,
                    "startedMillis": 1607690520026,
                    "endedMillis": 1607709294236,
                    "speed": 0.1,
                    "state": "successful"
                },
                "test_run": {
                    "readyMillis": 1607937250998,
                    "state": "pending"
                }
            }
        }
    }
}
```
```

## POST /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindex

Marks specified document types in specified clusters of an application as ready for [reindexing](../../operations/reindexing.html). Reindexing itself starts with the next redeployment of the application. To stop an ongoing reindexing, see [updating reindexing](#update-reindexing) below. All document types in all clusters are reindexed unless restricted, using parameters as specified:

| Parameters | 

| Name | Description |
| --- | --- |
| clusterId | A comma-separated list of content clusters to limit reindexing to. All clusters are reindexed if this is not present. |
| documentType | A comma-separated list of document types to limit reindexing to. All document types are reindexed if this is not present. |
| indexedOnly | Boolean: whether to mark reindexing ready only for document types with indexing mode _index_ and at least one field with the indexing statement `index`. Default is `false`. |
| speed | Number (0–10], default 1: Indexing pseudo speed - balance speed vs. resource use. Example: speed=0.1 |

 |
| Request body | N/A |
| Response | A human-readable message indicating what reindexing was marked as ready. |

Example:

`POST /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindex?clusterId=foo,bar&documentType=moo,baz&indexedOnly=true`

```
```
{
    "message": "Reindexing document types [moo, baz] in 'foo', [moo] in 'bar' of application default.default"
}
```
```

## PUT /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindex

Modifies [reindexing](../../operations/reindexing.html) of specified document types in specified clusters of an application. Specifically, this can be used to alter the pseudo-speed of the reindexing, optionally halting it by specifying a speed of `0`; reindexing for the specified types will remain dormant until either speed is increased again, or a new reindexing is triggered (see [trigger reindexing](#reindex)). Speed changes become effective with the next redeployment of the application. Reindexing for all document types in all clusters are affected if no other parameters are specified:

| Parameters | 

| Name | Description |
| --- | --- |
| clusterId | A comma-separated list of content clusters to limit the changes to. Reindexing for all clusters are modified if this is not present. |
| documentType | A comma-separated list of document types to limit the changes to. Reindexing for all document types are modified if this is not present. |
| indexedOnly | Boolean: whether to modify reindexing only for document types with indexing mode _index_ and at least one field with the indexing statement `index`. Default is `false`. |
| speed | Number [0–10], required: Indexing pseudo speed - balance speed vs. resource use. Example: speed=0.1 |

 |
| Request body | N/A |
| Response | A human-readable message indicating what reindexing was modified. |

Example:

`PUT /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindex?clusterId=foo,bar&documentType=moo,baz&speed=0.618`

```
```
{
    "message": "Set reindexing speed to '0.618' for document types [moo, baz] in 'foo', [moo] in 'bar' of application default.default"
}
```
```

## GET /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/content/[[path](#path)]

Returns content at the given path for an application. See [getting content](#content-get) for usage and response.

## DELETE /application/v2/tenant/default/application/default

Deletes an active application.

| Parameters | None |
| Request body | None |
| Response | 

Returns a message stating if the operation was successful or not

 |

Example:

`DELETE /application/v2/tenant/default/application/default`

```
```
{
    "message": "Application 'default' was deleted"
}
```
```

## GET /application/v2/host/[hostname]

Gets information about which tenant and application a hostname is used by.

| Parameters | None |
| Request body | None |
| Response | 

Returns a message with tenant and application details.

 |

Example:

`GET /application/v2/host/myhost.mydomain.com`

```
```
{
    "tenant": "default"
    "application": "default"
    "environment": "default"
    "region": "default"
    "instance": "default"
}
```
```

## Error Handling

Errors are returned using standard HTTP status codes. Any additional info is included in the body of the return call, JSON-formatted. The general format for an error response is:

```
```
{
    "error-code": "ERROR_CODE",
    "message": "An error message"
}
```
```

| HTTP status code | Error code | Description |
| --- | --- | --- |
| 400 | BAD\_REQUEST | Bad request. Client error. The error message should indicate the cause. |
| 400 | INVALID\_APPLICATION\_PACKAGE | There is an error in the application package. The error message should indicate the cause. |
| 400 | OUT\_OF\_CAPACITY | Not enough nodes available for the request to be fulfilled. |
| 401 | | Not authorized. The error message should indicate the cause. |
| 404 | NOT\_FOUND | Not found. E.g. when using a session-id that doesn't exist. |
| 405 | METHOD\_NOT\_ALLOWED | Method not implemented. E.g. using GET where only POST or PUT is allowed. |
| 409 | ACTIVATION\_CONFLICT | Conflict, returned when activating an application fails due to a conflict with other changes to the same application (in another session). Client should retry. |
| 500 | INTERNAL\_SERVER\_ERROR | Internal server error. Generic error. The error message should indicate the cause. |

## Access log

Requests are logged in the [access log](../../operations/access-logging.html) which can be found at _$VESPA\_HOME/logs/vespa/configserver/access-json.log_, example:

```
```
{
    "ip": "172.17.0.2",
    "time": 1655665104.751,
    "duration": 1.581,
    "responsesize": 230,
    "requestsize": 0,
    "code": 200,
    "method": "PUT",
    "uri": "/application/v2/tenant/default/session/2/prepared",
    "version": "HTTP/2.0",
    "agent": "vespa-deploy",
    "host": "b614c9ff04d7:19071",
    "scheme": "https",
    "localport": 19071,
    "peeraddr": "172.17.0.2",
    "peerport": 47480,
    "attributes": {
        "http2-stream-id":"1"
    }
}
```
```

## Use Cases

It is assumed that the tenant _default_ is already created in these use cases, and the application package is in _app_.

### Create, prepare and activate an application

Create a session with the application package:

```
$ (cd app && zip -r - .) | \
  curl -s --header Content-Type:application/zip --data-binary @- \
  "http://host:19071/application/v2/tenant/default/session"
```

Prepare the application with the URL in the _prepared_ link from the response:

```
$ curl -s -X PUT "http://host:19071/application/v2/tenant/default/session/1/prepared?applicationName=default"
```

Activate the application with the URL in the _activate_ link from the response:

```
$ curl -s -X PUT "http://host:19071/application/v2/tenant/default/session/1/active"
```

### Modify the application package

Dump _services.xml_ from session 1:

```
$ curl -s -X GET "http://host:19071/application/v2/tenant/default/session/1/content/services.xml"
```

```
```
<?xml version="1.0" encoding="utf-8" ?>
<services version="1.0">
    <admin version="2.0">
        <config name="config.logd">
            <logserver>
                <rpcport>12345</rpcport>
            </logserver>
        </config>
        <adminserver hostalias="node1" />
    </admin>
</services>
```
```

Session 1 is activated and cannot be changed - create a new session based on the active session:

```
$ curl -s -X POST "http://host:19071/application/v2/tenant/default/session?from=http://host:19071/application/v2/tenant/default/application/default/environment/default/region/default/instance/default"
```

Modify rpcport to 12346 in _services.xml_, deploy the change:

```
$ curl -s -X PUT --data-binary @app/services.xml \
  "http://host:19071/application/v2/tenant/default/session/2/content/services.xml"
```

Get _services.xml_ from session 2 to validate:

```
$ curl -s -X GET "http://host:19071/application/v2/tenant/default/session/2/content/services.xml"
```

```
```
<?xml version="1.0" encoding="utf-8" ?>
<services version="1.0">
    <admin version="2.0">
        <config name="config.logd">
            <logserver>
                <rpcport>12346</rpcport>
            </logserver>
        </config>
        <adminserver hostalias="node1" />
    </admin>
</services>
```
```

To add the file _files/test1.txt_, first create the directory, then add the file:

```
$ curl -s -X PUT "http://host:19071/application/v2/tenant/default/session/2/content/files/"
$ curl -s -X PUT --data-binary @app/files/test1.txt \
  "http://host:19071/application/v2/tenant/default/session/2/content/files/test1.txt"
```

Prepare and activate the session:

```
$ curl -s -X PUT "http://host:19071/application/v2/tenant/default/session/2/prepared?applicationName=fooapp"
$ curl -s -X PUT "http://host:19071/application/v2/tenant/default/session/2/active"
```

### Rollback

If you need to roll back to a previous version of the application package this can be achieved by creating a new session based on the previous known working version by passing the corresponding session-id in the _from_ argument, see [creating a session](#create-session)

Also see [rollback](/en/applications/deployment.html#rollback).

 Copyright © 2026 - [Cookie Preferences](#)

### On this page:

- [Deploy API](#page-title)
- [POST /application/v2/tenant/default/prepareandactivate](#prepareandactivate)
- [POST /application/v2/tenant/default/session](#create-session)
- [PUT /application/v2/tenant/default/session/[](#content-put)
- [GET /application/v2/tenant/default/session/[](#content-get)
- [DELETE /application/v2/tenant/default/session/[](#content-delete)
- [PUT /application/v2/tenant/default/session/[](#prepare-session)
- [GET /application/v2/tenant/default/session/[](#get-prepare-session)
- [PUT /application/v2/tenant/default/session/[](#activate-session)
- [GET /application/v2/tenant/default/application/](#get-application)
- [GET /application/v2/tenant/default/application/default](#get-application-info)
- [GET /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindexing](#reindexing)
- [POST /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindex](#reindex)
- [PUT /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/reindex](#update-reindexing)
- [GET /application/v2/tenant/default/application/default/environment/default/region/default/instance/default/content/[](#get-application-content)
- [DELETE /application/v2/tenant/default/application/default](#delete-application)
- [GET /application/v2/host/[hostname]](#get-host-info)
- [Error Handling](#error-handling)
- [Access log](#access-log)
- [Use Cases](#use-cases)
- [Create, prepare and activate an application](#use-case-start)
- [Modify the application package](#use-case-modify)
- [Rollback](#rollback)

