Deploy API

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

The response format is JSON. Examples are found in the use-cases. Also see the deploy guide.

The current API version is 2. The API port is 19071 - use 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 a session. The session-id is valid if it is an active session, or it was created before session lifetime 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 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

NameDefaultDescription
Request body

RequiredContentNote
Yes A compressed application package (with gzip or zip compression) Set Content-Type HTTP header to application/x-gzip or application/zip.
Response

See active.

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
NameDefaultDescription
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
RequiredContentNote
Yes, unless from parameter is used A compressed application package (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 to the application that was created.
  • A prepared 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]/content/[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]/content/[path]

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

Parameters

NameDefaultDescription
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]/content/[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]/prepared

Prepares an application with the session-id given.

Parameters

ParameterDefaultDescription
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 and a link to activate the session.

  • Log with any errors or warnings from preparing the application.
  • An activate URL for activating the application with this 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 for details.
    • Reindex actions are special refeed actions that Vespa handles automatically, if the reindex endpoint below is used.
    • Refeed actions require several steps to handle. See 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]/prepared

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

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

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

Parameters

ParameterDefaultDescription
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, a message and a URL to the activated application.

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

Triggers reindexing of specified document types in specified clusters of an application. Reindexing starts with the next redeployment of the application. To stop an ongoing reindexing, see updating reindexing below. All document types in all clusters are reindexed unless restricted, using parameters as specified:

Parameters
NameDescription
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 trigger 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], 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 triggered.

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 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). 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
NameDescription
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]

Returns content at the given path for an application. See getting content 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 codeError codeDescription
400BAD_REQUEST Bad request. Client error. The error message should indicate the cause.
400INVALID_APPLICATION_PACKAGE There is an error in the application package. The error message should indicate the cause.
400OUT_OF_CAPACITY Not enough nodes available for the request to be fulfilled.
401 Not authorized. The error message should indicate the cause.
404NOT_FOUND Not found. E.g. when using a session-id that doesn't exist.
405METHOD_NOT_ALLOWED Method not implemented. E.g. using GET where only POST or PUT is allowed.
409ACTIVATION_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.
500INTERNAL_SERVER_ERROR Internal server error. Generic error. The error message should indicate the cause.

Access log

Requests are logged in the access log 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

Also see rollback.