Vagrant
Vagrant Cloud API (Version 1)
Note
HashiCorp has moved Vagrant Cloud and migrated the boxes to HCP Vagrant Registry. Read the documentation to learn more about HCP Vagrant Registry.
Using the API
Vagrant Cloud provides an API for users to interact with Vagrant Cloud for experimentation, automation, or building new features and tools on top of our existing application.
Authentication
Some API endpoints require authentication to create new resources, update or delete existing resources, or to read a private resource.
Clients can authenticate using an authentication token. The token can be passed to Vagrant Cloud one of two ways:
- (Preferred) Set the
Authorization
header to"Bearer "
and the value of the authentication token. - Pass the authentication token as an
access_token
URL parameter (NOTE: deprecated).
Examples below will set the header, but feel free to use whichever method is easier for your implementation.
The X-Atlas-Token
header is also supported for backwards-compatibility.
Request and Response Format
Requests to Vagrant Cloud which include data attributes (POST
or PUT
/PATCH
) should set the Content-Type
header to "application/json"
, and include a valid JSON body with the request.
JSON responses may include an errors
key, which will contain an array of error strings, as well as a success
key.
For example:
{
"errors": ["Resource not found!"],
"success": false
}
Response Codes
Vagrant Cloud may respond with the following response codes, depending on the status of the request and context:
Success
200 OK
201 Created
204 No Content
Client Errors
401 Unauthorized
You do not have authorization to access the requested resource.
402 Payment Required
You are trying to access a resource which is delinquent on billing. Please contact the owner of the resource so that they can update their billing information.
403 Forbidden
You are attempting to use the system in a way which is not allowed.
There could be required request parameters that are missing, or one of the parameters is invalid.
Please check the response errors
key, and double-check the examples below for any discrepancies.
404 Not Found
The resource you are trying to access does not exist. This may also be returned if you attempt to access a private resource that you don't have authorization to view.
422 Unprocessable Entity
429 Too Many Requests
You are currently being rate-limited. Please decrease your frequency of usage, or contact us at support+vagrantcloud@hashicorp.com with a description of your use case so that we can consider creating an exception.
Server Errors
500 Internal Server Error
The server failed to respond to the request for an unknown reason. Please contact support+vagrantcloud@hashicorp.com with a description of the problem so that we can investigate.
503 Service Unavailable
Vagrant Cloud is temporarily in maintenance mode. Please check the HashiCorp Status Site for more information.
Creating a usable box from scratch
This assumes that you have a valid Vagrant Cloud authentication token. You can create one via the API, or create one on the Vagrant Cloud website.
In order to create a usable box on Vagrant Cloud, perform the following steps:
- Create a new box
- Create a new version
- Create a new provider
- Upload a box image for that provider
- Release the version
Example Requests
# Create a new box
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/boxes \
--data '{ "box": { "username": "myuser", "name": "test" } }'
# Create a new version
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/versions \
--data '{ "version": { "version": "1.2.3" } }'
# Create a new provider
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/providers \
--data '{ "provider": { "name": "virtualbox" } }'
# Prepare the provider for upload/get an upload URL
response=$(curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox/upload)
# Extract the upload URL from the response (requires the jq command)
upload_path=$(echo "$response" | jq .upload_path)
# Perform the upload
curl --request PUT "${upload_path}" --upload-file virtualbox-1.2.3.box
# Release the version
curl \
--request PUT \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/release
Authentication
Create a token
POST /api/v1/authenticate
Creates a new token for the given user.
Arguments
token
description
(Optional) - A description of the token.two_factor
code
- A two-factor authentication code. Required to use this API method if 2FA is enabled. See Request a 2FA code if not using a TOTP application.user
login
- Username or email address of the user authenticating.password
- The user's password.
Example Request
curl \
--request POST \
--header "Content-Type: application/json" \
https://app.vagrantup.com/api/v1/authenticate \
--data '
{
"token": {
"description": "Login from cURL"
},
"user": {
"login": "myuser",
"password": "secretpassword"
}
}
'
Example Response
{
"description": "Login from cURL",
"token": "qwlIE1qBVUafsg.atlasv1.FLwfJSSYkl49i4qZIu8R31GBnI9r8DrW4IQKMppkGq5rD264lRksTqaIN0zY9Bmy0zs",
"token_hash": "7598236a879ecb42cb0f25399d6f25d1d2cfbbc6333392131bbdfba325eb352795c169daa4a61a8094d44afe817a857e0e5fc7dc72a1401eb434577337d1246c",
"created_at": "2017-10-18T19:16:24.956Z"
}
Validate a token
GET /api/v1/authenticate
Responds 200 OK
if the authentication request was successful, otherwise responds 401 Unauthorized
.
Example Request
curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/authenticate
Delete a token
DELETE /api/v1/authenticate
Responds 204 OK
if the deletion request was successful, otherwise responds 401 Unauthorized
.
Example Request
curl \
--request DELETE \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/authenticate
Request a 2FA code
POST /api/v1/two-factor/request-code
Sends a 2FA code to the requested delivery method.
Arguments
two_factor
delivery_method
- A valid 2FA delivery method. Currently onlysms
is supported.user
login
- Username or email address of the user authenticating.password
- The user's password.
Example Request
curl \
--request POST \
--header "Content-Type: application/json" \
https://app.vagrantup.com/api/v1/two-factor/request-code \
--data '
{
"two_factor": {
"delivery_method": "sms"
},
"user": {
"login": "myuser",
"password": "secretpassword"
}
}
'
Example Response
{
"two_factor": {
"obfuscated_destination": "SMS number ending in 7890"
}
}
Organizations
Read an organization
GET /api/v1/user/:username
Example Request
curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/user/myuser
Example Response
{
"username": "myuser",
"avatar_url": "https://www.gravatar.com/avatar/130a640278870c3dada38b3d912ee022?s=460&d=mm",
"profile_html": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>\n",
"profile_markdown": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"boxes": []
}
Search
Search for boxes
GET /api/v1/search
Arguments
q
- (Optional) The search query. Results will match theusername
,name
, orshort_description
fields for a box. If omitted, the top boxes based onsort
andorder
will be returned (defaults to "downloads desc").provider
- (Optional) Filter results to boxes supporting for a specific provider.sort
- (Optional, default:"downloads"
) The field to sort results on. Can be one of"downloads"
,"created"
, or"updated"
.order
- (Optional, default:"desc"
) The order to return the sorted field in. Can be"desc"
os"asc"
.limit
- (Optional, default:10
) The number of results to return (max of 100).page
- (Optional, default:1
)
Example Request
curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
"https://app.vagrantup.com/api/v1/search?q=test&provider=virtualbox"
Example Response
{
"boxes": [
{
"created_at": "2017-10-20T14:19:59.842Z",
"updated_at": "2017-10-20T15:23:53.363Z",
"tag": "myuser/test",
"name": "test",
"short_description": "My dev box",
"description_html": "<p>My development Vagrant box</p>\n",
"username": "myuser",
"description_markdown": "My development Vagrant box",
"private": true,
"downloads": 123,
"current_version": {
"version": "1.2.3",
"status": "active",
"description_html": "<p>A new version</p>\n",
"description_markdown": "A new version",
"created_at": "2017-10-20T15:23:17.184Z",
"updated_at": "2017-10-20T15:23:53.355Z",
"number": "1.2.3",
"release_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/release",
"revoke_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/revoke",
"providers": [
{
"name": "virtualbox",
"hosted": false,
"hosted_token": null,
"original_url": "https://example.com/virtualbox-1.2.3.box",
"created_at": "2017-10-20T15:23:35.718Z",
"updated_at": "2017-10-20T15:23:35.718Z",
"download_url": "https://vagrantcloud.com/myuser/boxes/test/versions/1.2.3/providers/virtualbox.box"
}
]
}
}
]
}
Boxes
Read a box
GET /api/v1/box/:username/:name
Example Request
curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test
Example Response
{
"created_at": "2017-10-20T14:19:59.842Z",
"updated_at": "2017-10-20T15:23:53.363Z",
"tag": "myuser/test",
"name": "test",
"short_description": "My dev box",
"description_html": "<p>My development Vagrant box</p>\n",
"username": "myuser",
"description_markdown": "My development Vagrant box",
"private": true,
"downloads": 123,
"current_version": {
"version": "1.2.3",
"status": "active",
"description_html": "<p>A new version</p>\n",
"description_markdown": "A new version",
"created_at": "2017-10-20T15:23:17.184Z",
"updated_at": "2017-10-20T15:23:53.355Z",
"number": "1.2.3",
"release_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/release",
"revoke_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/revoke",
"providers": [
{
"name": "virtualbox",
"hosted": false,
"hosted_token": null,
"original_url": "https://example.com/virtualbox-1.2.3.box",
"created_at": "2017-10-20T15:23:35.718Z",
"updated_at": "2017-10-20T15:23:35.718Z",
"download_url": "https://vagrantcloud.com/myuser/boxes/test/versions/1.2.3/providers/virtualbox.box"
}
]
},
"versions": [
{
"version": "1.2.3",
"status": "active",
"description_html": "<p>A new version</p>\n",
"description_markdown": "A new version",
"created_at": "2017-10-20T15:23:17.184Z",
"updated_at": "2017-10-20T15:23:53.355Z",
"number": "1.2.3",
"release_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/release",
"revoke_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/revoke",
"providers": [
{
"name": "virtualbox",
"hosted": false,
"hosted_token": null,
"original_url": "https://example.com/virtualbox-1.2.3.box",
"created_at": "2017-10-20T15:23:35.718Z",
"updated_at": "2017-10-20T15:23:35.718Z",
"download_url": "https://vagrantcloud.com/myuser/boxes/test/versions/1.2.3/providers/virtualbox.box"
}
]
}
]
}
Create a box
POST /api/v1/boxes
Arguments
box
username
- The username of the organization that will own this box.name
- The name of the box.short_description
- A short summary of the box.description
- A longer description of the box. Can be formatted with Markdown.is_private
(Optional, default:true
) - Whether or not this box is private.
Example Request
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/boxes \
--data '
{
"box": {
"username": "myuser",
"name": "test",
"short_description": "My dev box",
"description": "My development Vagrant box",
"is_private": true
}
}
'
Example Response
Response body is identical to Reading a box.
Update a box
PUT /api/v1/box/:username/:name
Arguments
box
name
- The name of the box.short_description
- A short summary of the box.description
- A longer description of the box. Can be formatted with Markdown.is_private
(Optional, default:true
) - Whether or not this box is private.
Example Request
curl \
--request PUT \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test \
--data '
{
"box": {
"name": "test",
"short_description": "My dev box",
"description": "My development Vagrant box",
"is_private": true
}
}
'
Delete a box
DELETE /api/v1/box/:username/:name
Example Request
curl \
--request DELETE \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test
Example Response
Response body is identical to Reading a box.
Versions
Read a version
GET /api/v1/box/:username/:name/version/:version
Example Request
curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3
Example Response
{
"version": "1.2.3",
"status": "active",
"description_html": "<p>A new version</p>\n",
"description_markdown": "A new version",
"created_at": "2017-10-20T15:23:17.184Z",
"updated_at": "2017-10-20T15:23:53.355Z",
"number": "1.2.3",
"release_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/release",
"revoke_url": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/revoke",
"providers": [
{
"name": "virtualbox",
"hosted": false,
"hosted_token": null,
"original_url": "https://example.com/virtualbox-1.2.3.box",
"created_at": "2017-10-20T15:23:35.718Z",
"updated_at": "2017-10-20T15:23:35.718Z",
"download_url": "https://vagrantcloud.com/myuser/boxes/test/versions/1.2.3/providers/virtualbox.box"
}
]
}
Create a version
POST /api/v1/box/:username/:name/versions
New versions start as unreleased
. You must create a valid provider before releasing a new version.
Arguments
version
version
- The version number of this version.description
- A description for this version. Can be formatted with Markdown.
Example Request
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/versions \
--data '
{
"version": {
"version": "1.2.3",
"description": "A new version"
}
}
'
Example Response
Response body is identical to Reading a version.
Update a version
PUT /api/v1/box/:username/:name/version/1.2.3
Arguments
version
version
- The version number of this version.description
- A description for this version. Can be formatted with Markdown.
Example Request
curl \
--request PUT \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3 \
--data '
{
"version": {
"version": "1.2.3",
"description": "A new version"
}
}
'
Example Response
Response body is identical to Reading a version.
Delete a version
DELETE /api/v1/box/:username/:name/version/:version
Example Request
curl \
--request DELETE \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3
Example Response
Response body is identical to Reading a version.
Release a version
PUT /api/v1/box/:username/:name/version/1.2.3/release
Example Request
curl \
--request PUT \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/release
Example Response
Response body is identical to Reading a version.
Revoke a version
PUT /api/v1/box/:username/:name/version/1.2.3/revoke
Example Request
curl \
--request PUT \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/revoke
Example Response
Response body is identical to Reading a version.
Providers
Read a provider
GET /api/v1/box/:username/:name/version/:version/provider/:provider
Example Request
curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox
Example Response
{
"name": "virtualbox",
"hosted": false,
"hosted_token": null,
"original_url": "https://example.com/virtualbox-1.2.3.box",
"created_at": "2017-10-20T15:23:35.718Z",
"updated_at": "2017-10-20T15:23:35.718Z",
"download_url": "https://vagrantcloud.com/myuser/boxes/test/versions/1.2.3/providers/virtualbox.box",
"checksum": "a59e7332e8bbe896f11f478fc61fa8a6",
"checksum_type": "md5"
}
Create a provider
POST /api/v1/box/:username/:name/version/:version/providers
Arguments
provider
name
- The name of the provider.url
- A valid URL to download this provider. If omitted, you must upload the Vagrant box image for this provider to Vagrant Cloud before the provider can be used.checksum
- Computed checksum of the box assets. When set, Vagrant will compute the checksum of the downloaded box asset and validate it matches this value.checksum_type
- Type of checksum used. Currently supported values: md5, sha1, sha256, sha384, and sha512
Example Request
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/providers \
--data '
{
"provider": {
"checksum": "a59e7332e8bbe896f11f478fc61fa8a6",
"checksum_type": "md5",
"name": "virtualbox",
"url": "https://example.com/virtualbox-1.2.3.box"
}
}
'
Example Response
Response body is identical to Reading a provider.
Update a provider
PUT /api/v1/box/:username/:name/version/:version/provider/:provider
Arguments
Example Request
curl \
--request PUT \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox \
--data '
{
"provider": {
"checksum": "a59e7332e8bbe896f11f478fc61fa8a6",
"checksum_type": "md5",
"name": "virtualbox",
"url": "https://example.com/virtualbox-1.2.3.box"
}
}
'
Example Response
Response body is identical to Reading a provider.
Delete a provider
DELETE /api/v1/box/:username/:name/version/:version/provider/:provider
Example Request
curl \
--request DELETE \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox
Example Response
Response body is identical to Reading a provider.
Upload a provider
GET /api/v1/box/:username/:name/version/:version/provider/:provider/upload
Prepares the provider for upload, and returns a JSON blob containing an upload_path
.
The upload must begin shortly after the response is returned, otherwise the URL will expire. If the URL expires, you can request this same API method again for a new upload URL.
Example Request
response=$(curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox/upload)
# Requires the jq command
upload_path=$(echo "$response" | jq .upload_path)
curl \
--request PUT \
--upload-file virtualbox-1.2.3.box \
"${upload_path}"
Example Response
{
"upload_path": "https://archivist.hashicorp.com/v1/object/630e42d9-2364-2412-4121-18266770468e"
}
Upload a provider directly to backend storage
GET /api/v1/box/:username/:name/version/:version/provider/:provider/upload/direct
Prepares the provider for upload. This version of the upload API allows uploading the box asset directly to the backend storage. It requires a two step process for uploading the box assets. First uploading the asset to storage and then finalizing the upload within Vagrant Cloud via a provided callback.
The request returns a JSON blob containing two fields:
upload_path
- URL toPUT
the box assetcallback
- Vagrant Cloud callback URL to finalize upload
The box asset is uploaded directly to the URL provided by the upload_path
via a PUT
request. Once complete, a PUT
request to the URL
provided in the callback
field (complete with authentication header) finalizes the upload.
The upload must begin shortly after the response is returned, otherwise the URL will expire. If the URL expires, you can request this same API method again for a new upload URL.
Example Request
response=$(curl \
--request GET \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox/upload/direct)
# Requires the jq command
upload_path=$(echo "$response" | jq .upload_path)
callback=$(echo "$response" | jq .callback)
curl \
--request PUT \
--upload-file virtualbox-1.2.3.box \
"${upload_path}"
curl
--request PUT \
--header "Authorization: Bearer $VAGRANT_CLOUD_TOKEN" \
"${callback}"
Example Response
{
"upload_path": "https://remote-storage.example.com/bucket/630e42d9-2364-2412-4121-18266770468e?auth=9023wqfda",
"callback": "https://app.vagrantup.com/api/v1/box/myuser/test/version/1.2.3/provider/virtualbox/upload/direct/630e42d9-2364-2412-4121-18266770468e"
}