Select programming language for code examples

linkThe release object

Below you will find the various attributes for the release resource, as well as the release resource's relationships. Release versioning must follow the semver spec.

linkAttributes

  • linkdata.attributes.name

    string

    The human-readable name of the release. This can be used as an optional label.

  • linkdata.attributes.description

    string

    The description of the release. Useful for releases notes and the like.

  • linkdata.attributes.channel

    string

    The channel for the release. One of: stable, rc, beta, alpha, or dev.

  • linkdata.attributes.status

    string

    The release's status. Draft and yanked releases are unlisted. One of: DRAFT, PUBLISHED, or YANKED.

  • linkdata.attributes.tag

    string

    The tag for the release, used for lookups. This can be an arbitrary string, e.g. latest or app@latest, or something reproducible, such as an MD5 or other checksum, to prevent duplicates. This value must be unique, even across products.

  • linkdata.attributes.version

    semver

    The version of the release. This must be a valid semantic version (semver) string. Do not include a v prefix. This value must be unique per-product. The version may include prerelease and build tags.

  • linkdata.attributes.semver

    object<string, any>read only

    Object containing deconstructed key-value semver components.

  • linkdata.attributes.metadata

    object<string, any>

    Object containing release metadata. This can be used to store things such as hash checksums, e.g. SHA-256 and SHA-512, for integrity verification after download, or for release notes.

  • linkdata.attributes.created

    timestamp (iso8601)read only

    When the release was created.

  • linkdata.attributes.updated

    timestamp (iso8601)read only

    When the release was last updated.

  • linkdata.attributes.yanked

    timestamp (iso8601)read only

    When the release was yanked.

linkRelationships

  • linkdata.relationships.account

    individual

    The account that the release belongs to.

  • linkdata.relationships.environment

    individualent onlyThese relationships are only available for accounts on an Ent tier.

    The environment that the release belongs to.

  • linkdata.relationships.product

    individual

    The product that the release belongs to.

  • linkdata.relationships.package

    individual

    The package that the release belongs to.

  • linkdata.relationships.entitlements

    collection

    The entitlements constrained to the release (through constraints).

  • linkdata.relationships.constraints

    collection

    The constraints for the release. Constraints can be used to require certain license entitlements in order to access a release, e.g. ACCESS_V1 and ACCESS_V2. If the licensee lacks an entitlement constraint, access will be denied.

  • linkdata.relationships.artifacts

    collection

    The artifacts for the release. These represent files associated with the release.

Example object

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0-beta.2",
"description": null,
"channel": "beta",
"status": "PUBLISHED",
"tag": "latest",
"version": "2.0.0-beta.2",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": "beta.2",
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkCreate a release

Creates a new release resource. Releases represent versioned "buckets" to put artifacts into. New releases will have a DRAFT status, and must be published before being listed.

After creating a release (or "bucket"), artifacts can be added to it via the create artifact endpoint before publishing the release.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

linkAttributes

  • linkdata.attributes.name

    stringoptional

    The human-readable name of the release. This can be used as an optional label.

  • linkdata.attributes.description

    stringoptional

    The description of the release. Useful for releases notes and the like.

  • linkdata.attributes.status

    stringoptionaldefault=DRAFT

    The release's initial status. Draft releases are unlisted. One of: DRAFT or PUBLISHED.

  • linkdata.attributes.version

    semverrequired

    The version of the release. This must be a valid semantic version (semver) string. Do not include a v prefix. This value must be unique per-product. The version may include prerelease and build tags.

  • linkdata.attributes.tag

    stringoptional

    The tag for the release, used for lookups. This can be an arbitrary string, e.g. latest or app@latest, or something reproducible, such as an MD5 or other checksum, to prevent duplicates. This value must be unique, even across products.

  • linkdata.attributes.channel

    stringrequired

    The channel for the release. One of: stable, rc, beta, alpha, or dev. For prereleases, i.e. non-stable, the channel must match the version's prerelease tag.

  • linkdata.attributes.metadata

    object<string, any>optional

    Object containing release metadata. This can be used to store things such as hash checksums, e.g. SHA-256 and SHA-512, for integrity verification after download, or for release notes.

linkRelationships

  • linkdata.relationships.product

    linkage<product>required

    The product the release is for.

  • linkdata.relationships.package

    linkage<package>optional

    The package the release is for.

  • linkdata.relationships.constraints

    array<constraint>optional

    The constraints for the release. Constraints can be used to require certain license entitlements in order to access a release, e.g. ACCESS_V1 and ACCESS_V2. If the licensee lacks an entitlement constraint, access will be denied.

linkReturns

A 201 Created response will be returned along with the new release object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases", {
method: "POST",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
body: JSON.stringify({
"data": {
"type": "release",
"attributes": {
"name": "Product v2-alpha.1",
"version": "2.0.0-alpha.1",
"channel": "alpha",
"tag": "latest"
},
"relationships": {
"product": {
"data": {
"type": "product",
"id": "855ef427-6f68-4153-ab88-e63c631014c3"
}
},
"constraints": {
"data": [
{
"type": "constraint",
"relationships": {
"entitlement": {
"data": { "type": "entitlement", "id": "2f9397b0-bbde-4219-a761-1307f338261f" }
}
}
},
{
"type": "constraint",
"relationships": {
"entitlement": {
"data": { "type": "entitlement", "id": "481cc294-3f91-4efe-b471-90d14ecd5887" }
}
}
}
]
}
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/<account>/releases",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
},
data=json.dumps({
"data": {
"type": "release",
"attributes": {
"name": "Product v2-alpha.1",
"version": "2.0.0-alpha.1",
"channel": "alpha",
"tag": "latest"
},
"relationships": {
"product": {
"data": {
"type": "product",
"id": "855ef427-6f68-4153-ab88-e63c631014c3"
}
},
"constraints": {
"data": [
{
"type": "constraint",
"relationships": {
"entitlement": {
"data": { "type": "entitlement", "id": "2f9397b0-bbde-4219-a761-1307f338261f" }
}
}
},
{
"type": "constraint",
"relationships": {
"entitlement": {
"data": { "type": "entitlement", "id": "481cc294-3f91-4efe-b471-90d14ecd5887" }
}
}
}
]
}
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases",
method: .post,
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
],
parameters: [
"data": [
"type": "release",
"attributes": [
"name": "Product v2-alpha.1",
"version": "2.0.0-alpha.1",
"channel": "alpha",
"tag": "latest"
],
"relationships": [
"product": [
"data": [
"type": "product",
"id": "855ef427-6f68-4153-ab88-e63c631014c3"
]
],
"constraints": [
"data": [
[
"type": "constraint",
"relationships": [
"entitlement": [
"data": ["type": "entitlement", "id": "2f9397b0-bbde-4219-a761-1307f338261f"]
]
]
],
[
"type": "constraint",
"relationships": [
"entitlement": [
"data": ["type": "entitlement", "id": "481cc294-3f91-4efe-b471-90d14ecd5887"]
]
]
]
]
]
]
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("releases", Method.POST);
 
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddJsonBody(new {
data = new {
type = "releases",
attributes = new {
name = "Product v2-alpha.1",
version = "2.0.0-alpha.1",
channel = "alpha",
tag = "latest"
},
relationships = new {
product = new {
data = new { type = "products", id = "855ef427-6f68-4153-ab88-e63c631014c3" }
},
constraints = new {
data = [
new {
type = "constraint",
relationships = new {
entitlement = new {
data = new { type = "entitlement", id = "2f9397b0-bbde-4219-a761-1307f338261f" }
}
}
},
new {
type = "constraint",
relationships = new {
entitlement = new {
data = new { type = "entitlement", id = "481cc294-3f91-4efe-b471-90d14ecd5887" }
}
}
}
]
}
}
}
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to mapOf(
"type" to "releases",
"attributes" to mapOf(
"name" to "Product v2-alpha.1",
"version" to "2.0.0-alpha.1",
"channel" to "alpha",
"tag" to "latest"
),
"relationships" to mapOf(
"product" to mapOf(
"data" to mapOf("type" to "products", "id" to "855ef427-6f68-4153-ab88-e63c631014c3")
)
)
)
))
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", ofEntries(
entry("type", "releases"),
entry("attributes", ofEntries(
entry("name" ,"Product v2-alpha.1"),
entry("version", "2.0.0-alpha.1"),
entry("channel", "alpha")
entry("tag", "latest")
),
entry("relationships", ofEntries(
entry("product", ofEntries(
entry("data", ofEntries(
entry("type", "products"),
entry("id", "855ef427-6f68-4153-ab88-e63c631014c3")
))
))
))
))
));
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value attrs;
attrs["name"] = value::string("Product v2-alpha.1");
attrs["version"] = value::string("2.0.0-alpha.1");
attrs["channel"] = value::string("alpha");
attrs["tag"] = value::string("latest");
 
value product_linkage;
product_linkage["type"] = value::string("products");
product_linkage["id"] = value::string("855ef427-6f68-4153-ab88-e63c631014c3");
 
value product;
product["data"] = product_linkage;
 
value rels;
rels["product"] = product;
 
value data;
data["type"] = value::string("releases");
data["attributes"] = attrs;
data["relationships"] = rels;
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases");
req.set_method(methods::POST);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X POST https://api.keygen.sh/v1/accounts/<account>/releases \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-d '{
"data": {
"type": "release",
"attributes": {
"name": "Product v2-alpha.1",
"version": "2.0.0-alpha.1",
"channel": "alpha",
"tag": "latest"
},
"relationships": {
"product": {
"data": {
"type": "product",
"id": "855ef427-6f68-4153-ab88-e63c631014c3"
}
}
}
}
}'

Example response / 201 Created

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0-alpha.1",
"description": null,
"channel": "alpha",
"status": "DRAFT",
"tag": "latest",
"version": "2.0.0-alpha.1",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": "alpha.1",
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkRetrieve a release

Retrieves the details of an existing release.

linkAuthentication

  • linkBearer

    optional

    An authentication token with privileges to read the release: either an admin, the product it belongs to, an entitled license (via license key or a license token), or a user with an entitled license. If the product's distribution strategy is OPEN, no authentication is required.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to be retrieved.

linkQuery Parameters

  • linkproduct

    string

    The identifier (UUID) of the product to filter by.

    /v1/accounts/<account>/releases/1.0.0?product=3ab38aae-bbf7-4846-9c32-af9d94bf5ad4
  • linkpackage

    string

    The identifier (UUID) or key of the package to filter by.

    /v1/accounts/<account>/releases/1.0.0?package=machineid

linkReturns

A 200 OK response will be returned along with a release object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817", {
method: "GET",
headers: {
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
headers={
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
headers: [
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
Method.GET
);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Accept", "application/vnd.api+json");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/30c64dcd-a74d-4f0d-8479-8745172a4817");
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817 \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/vnd.api+json'

Example response / 200 OK

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0-beta.2",
"description": null,
"channel": "beta",
"status": "PUBLISHED",
"tag": "latest",
"version": "2.0.0-beta.2",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": "beta.2",
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkUpdate a release

Updates the specified release resource by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to be updated.

linkAttributes

  • linkdata.attributes.name

    stringoptional

    The human-readable name of the release. This can be used as an optional label.

  • linkdata.attributes.description

    stringoptional

    The description of the release. Useful for releases notes and the like.

  • linkdata.attributes.tag

    stringoptional

    The tag for the release, used for lookups. This can be an arbitrary string, e.g. latest or app@latest, or something reproducible, such as an MD5 or other checksum, to prevent duplicates. This value must be unique, even across products.

  • linkdata.attributes.metadata

    object<string, any>optional

    Object containing release metadata.

linkReturns

A 200 OK response will be returned along with the updated license object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817", {
method: "PATCH",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
body: JSON.stringify({
"data": {
"type": "releases",
"attributes": {
"tag": "latest"
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.patch(
"https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
data=json.dumps({
"data": {
"type": "releases",
"attributes": {
"tag": "latest"
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
method: .patch,
headers: [
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
],
parameters: [
"data": [
"type": "releases",
"attributes": [
"tag": "latest"
]
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
Method.PATCH
);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
 
request.AddJsonBody(new {
data = new {
type = "releases",
attributes = new {
tag = "latest"
}
}
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to mapOf(
"type" to "releases",
"attributes" to mapOf(
"tag" to "latest"
)
)
))
 
val res = Unirest.patch("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", ofEntries(
entry("type", "releases"),
entry("attributes", ofEntries(
entry("tag", "latest")
))
))
));
 
HttpResponse<JsonNode> res = Unirest.patch("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value attrs;
attrs["tag"] = value::string("latest");
 
value data;
data["type"] = value::string("releases");
data["attributes"] = attrs;
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/30c64dcd-a74d-4f0d-8479-8745172a4817");
req.set_method(methods::PATCH);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X PATCH https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817 \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-d '{
"data": {
"type": "releases",
"attributes": {
"tag": "latest"
}
}
}'

Example response / 200 OK

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0-beta.2",
"description": null,
"channel": "beta",
"status": "PUBLISHED",
"tag": "latest",
"version": "2.0.0-beta.2",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": "beta.2",
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkDelete a release

Permanently deletes a release. It cannot be undone. As an alternative, please see the yank release action, which will retain the release resource but it will no longer be listed.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to be deleted.

linkReturns

A 204 No Content response will be returned.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817", {
method: "DELETE",
headers: {
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
})
import requests
 
res = requests.delete(
"https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
headers={
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
)
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
method: .delete,
headers: [
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
]
).responseJSON { response in
let status = response.response?.statusCode
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/30c64dcd-a74d-4f0d-8479-8745172a4817",
Method.DELETE
);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Accept", "application/vnd.api+json");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/30c64dcd-a74d-4f0d-8479-8745172a4817");
req.set_method(methods::DELETE);
 
client.request(req)
.then([](http_response res) {
auto status = res.status_code();
})
.wait();
curl -X DELETE https://api.keygen.sh/v1/accounts/<account>/releases/30c64dcd-a74d-4f0d-8479-8745172a4817 \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/vnd.api+json'

Example response / 204 No Content

No content

linkList all releases

Returns a list of releases. The releases are returned sorted by creation date, with the most recent published releases appearing first. Resources are automatically scoped to the authenticated bearer e.g. when authenticated as a license or user, only releases accessible by the requestor will be listed.

linkAuthentication

  • linkBearer

    optional

    An authentication token with privileges to read the releases: either an admin, the product the releases belong to, an entitled license (via license key or a license token), or a user with an entitled license. If the product's distribution strategy is OPEN, no authentication is required.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

linkQuery Parameters

  • linklimit

    integerdefault=10

    A limit on the number of releases to be returned. Limit must be a number between 1 and 100.

    /v1/accounts/<account>/releases?limit=25
  • linkpage

    object<string, integer>

    Object containing page size and page number. Page size must be a number between 1 and 100.

    /v1/accounts/<account>/releases?page[size]=15&page[number]=2
  • linkproduct

    string

    The identifier (UUID) of the product to filter by.

    /v1/accounts/<account>/releases?product=3ab38aae-bbf7-4846-9c32-af9d94bf5ad4
  • linkpackage

    string

    The identifier (UUID) or key of the package to filter by.

    /v1/accounts/<account>/releases?package=machineid
  • linkengine

    string

    The identifier (UUID) or key of the engine to filter by.

    /v1/accounts/<account>/releases?engine=pypi
  • linkchannel

    string

    The identifier (UUID) or key of the channel to filter by.

    /v1/accounts/<account>/releases?channel=stable
  • linkentitlements

    array<string>

    An array of entitlement codes to filter by. Only releases that have the provided constraints, or fewer, will be returned.

    For example, if we provide the entitlements FOO and BAR, this will return all releases that have constraints on FOO and/or BAR, or no constraints at all, but none that have BAZ.
    /v1/accounts/<account>/releases?entitlements[]=FOO&entitlements[]=BAR
  • linkstatus

    string

    The status of the release to filter by. One of: DRAFT, PUBLISHED, or YANKED.

    /v1/accounts/<account>/releases?status=PUBLISHED

linkReturns

A 200 OK response will be returned along with a list of release objects.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases?limit=15", {
method: "GET",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/releases?limit=15",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases?limit=15",
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("releases", Method.GET);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddParameter("limit", 15);
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
uri_builder uri("/releases");
uri.append_query("limit", 15);
 
req.set_request_uri(uri.to_uri());
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/releases?limit=15 -g \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": [
{
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0-beta.2",
"description": null,
"channel": "beta",
"status": "PUBLISHED",
"tag": "latest",
"version": "2.0.0-beta.2",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": "beta.2",
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
},
]
}

linkUpgrade a release

Upgrades an existing release, returning the latest release for the product within the provided constraints. For upgrades, releases are sorted by semantic version, not by creation time like with the list endpoint.

After upgrading, the resulting release can be used for subsequent requests, e.g. to fetch a particular artifact of the release, dependent on platform.

By default, upgrades are scoped to the current release's channel. For example, when requesting an upgrade for v1.0.0, only other stable releases will be elligible to be returned. Similarly, when requesting an upgrade for v1.2.3-beta.1, other beta releases will also be elligible. You can use the channel query parameter to override this behavior.

When no upgrade is available, e.g. the current release is the latest version for the current constraints, a 404 Not Found error will be returned.

For example, say you're upgrading a CLI app from v1 to v2, and there are a lot of v1 patch releases in between. When requesting an upgrade for v1, the latest v2 release will be returned. When requesting an upgrade for the latest v2 release, an error will be returned. When requesting an upgrade for v1 while constrained to v1, i.e. ?constraint=1.0, then the latest v1 release will be returned, e.g. v1.2.3.

linkAuthentication

  • linkBearer

    optional

    An authentication token with privileges to upgrade the release: either an admin, the product it belongs to, an entitled license (via license key or a license token), or a user with an entitled license. If the product's distribution strategy is OPEN, no authentication is required.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to be upgraded.

linkQuery Parameters

  • linkproduct

    string

    The identifier (UUID) of the product to scope the upgrade to, in case of a potential conflict with another product.

    /v1/accounts/<account>/releases/1.0.0/upgrade?product=3ab38aae-bbf7-4846-9c32-af9d94bf5ad4
  • linkconstraint

    string

    The version constraint for the upgrade. For example, constraint=1.0 will constrain all upgrades to version 1.x, while constraint=1.0.0 will constrain to version 1.0.x. This is useful if a given license is only entitled to a specific version range. Major version is required.

    You can also use constraints to constrain to a specific prerelease tag, such as constraint=1-beta, or to a specific build tag like constraint=1%2Bfoo (note the URL-encoded + symbol).
    /v1/accounts/<account>/releases/<release>/upgrade?constraint=1.0
  • linkpackage

    string

    The identifier (UUID) or key of the package to scope the upgrade to, in case of a potential conflict with another package.

    /v1/accounts/<account>/releases/<release>/upgrade?package=ff04d1c4-cc04-4d19-985a-cb113827b821
  • linkchannel

    string

    The release channel. One of: stable, rc, beta, alpha or dev. The rc channel will include stable releases. The beta channel will include rc and stable. Alpha will include beta, rc, and stable. Dev will only include releases on the dev channel (you can think of it as 'nightly' or 'edge', i.e. following a master branch).

    /v1/accounts/<account>/releases/<release>/upgrade?channel=beta

linkReturns

A 200 OK response will be returned along with a release object. When no upgrade is available, a 404 Not Found error will be returned.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>/upgrade

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/1.2.3/upgrade", {
method: "GET",
headers: {
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/releases/1.2.3/upgrade",
headers={
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/1.2.3/upgrade",
headers: [
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/1.2.3/upgrade",
Method.GET
);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Accept", "application/vnd.api+json");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/1.2.3/upgrade")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/1.2.3/upgrade")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/1.2.3/upgrade");
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/releases/1.2.3/upgrade \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/vnd.api+json'

Example response / 200 OK

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0",
"description": null,
"channel": "stable",
"status": "PUBLISHED",
"tag": "latest",
"version": "2.0.0",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": null,
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkRelease actions

Actions for the release resource.

linkPublish a release

Publishes a release. This action will set the release's status to PUBLISHED, listing the release for all entitled users.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to publish the release: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to publish.

linkReturns

A 200 OK response will be returned along with the published release object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>/actions/publish

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish", {
method: "POST",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish",
method: .post,
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish",
Method.POST
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish");
req.set_method(methods::POST);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl -X POST https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/publish \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0",
"description": null,
"channel": "stable",
"status": "PUBLISHED",
"tag": "latest",
"version": "2.0.0",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": null,
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": null
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkYank a release

Yanks a release. This action will set the release's status to YANKED, delisting the release for all users. The release can be republished at a later date, or left alone.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to yank the release: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to yank.

linkReturns

A 200 OK response will be returned along with the yanked release object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>/actions/yank

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank", {
method: "POST",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank",
method: .post,
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank",
Method.POST
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank");
req.set_method(methods::POST);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl -X POST https://api.keygen.sh/v1/accounts/<account>/releases/3b4b4688-99e9-48d0-8b7e-14e4dcb025e3/actions/yank \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": {
"id": "30c64dcd-a74d-4f0d-8479-8745172a4817",
"type": "releases",
"attributes": {
"name": "Keygen CLI v2.0.0",
"description": null,
"channel": "stable",
"status": "YANKED",
"tag": "latest",
"version": "2.0.0",
"semver": {
"major": 2,
"minor": 0,
"patch": 0,
"prerelease": null,
"build": null
},
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z",
"yanked": "2022-06-01T08:47:21.995Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/product"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
},
"package": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/package"
},
"data": null
},
"entitlements": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/entitlements"
}
},
"constraints": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/constraints"
}
},
"artifacts": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/artifacts"
}
},
"upgrade": {
"links": {
"related": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb/upgrade"
}
}
},
"links": {
"self": "/v1/accounts/<account>/releases/46003a57-3e0a-4fc8-99a8-0f089720f1eb"
}
}
}

linkRelease relationships

Relationship endpoints for the release resource.

linkDownload an artifact

Returns an artifact for the release. The same rules apply as the main artifact download endpoint, in that only entitled users may download the artifact.

This endpoint is especially useful when accessing artifacts as part of an upgrade. For example, you can request an upgrade, and then download the appropriate artifact for the release returned from the upgrade request.

As an example, consider the following upgrade flow, from GET /releases/1.0.0/upgrade => 2.0.0 to GET /releases/2.0.0/artifacts/App.zip.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to view the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release.

  • link<artifact>

    stringrequired

    The identifier (UUID) or filename of the artifact to download.

linkReturns

A 303 See Other status will be returned redirecting to the download URL for the artifact, hosted on AWS S3. Follow the redirect's Location header to download the artifact's file.

Please note: If you receive a 400 error from AWS S3, you may need to configure your HTTP client to not automatically follow redirects. Some HTTP clients will insecurely replay the entire request, including your Keygen Authorization header, to the cross-origin AWS S3 resource, resulting in a 400 response from S3. You can manually follow the redirect by issuing a GET request to the Location header, without the superfluous headers.

Alternatively, you can pass in your API token via the request's query parameters, e.g. ?auth=token:activ-XXX or ?auth=license:XXX, instead of the Authorization header.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>/artifacts/<artifact>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts/install.sh", {
method: "GET",
headers: {
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts/install.sh",
headers={
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts/install.sh",
headers: [
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("artifacts", Method.GET);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Accept", "application/vnd.api+json");
 
request.AddParameter("list", 15);
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts/install.sh")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts/install.sh")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
uri_builder uri("/releases/2.0.0/artifacts/install.sh");
 
req.set_request_uri(uri.to_uri());
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts/install.sh -g \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/vnd.api+json'

Example response / 200 OK

{
"data": [
{
"id": "0dad8516-f071-4573-bcea-d774e81c4a37",
"type": "artifacts",
"attributes": {
"filename": "install.sh",
"filetype": "sh",
"filesize": 3097,
"platform": null,
"arch": null,
"signature": "q73uw0RZ3MDooFeIUYP2iMYSWsHdL2MIhnq74IiGVEVXx0Qxeuh6eWDvlbkZ15RmjxRlTeJFjTwOubF9Hdc9Aw",
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg",
"status": "UPLOADED",
"metadata": {},
"created": "2022-05-30T13:28:01.592Z",
"updated": "2022-05-30T13:28:31.786Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"release": {
"links": {
"related": "/v1/accounts/<account>/releases/8157c656-c60f-4b82-b93f-3b3ed73abf80"
},
"data": {
"type": "releases",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
}
}
},
"links": {
"related": "/v1/accounts/<account>/releases/8157c656-c60f-4b82-b93f-3b3ed73abf80/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
"self": "/v1/accounts/<account>/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37"
}
},
]
}

linkList artifacts

Returns a list of artifacts for the release. The artifacts are returned sorted by creation date, with the most recent artifacts appearing first.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to view the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to list artifacts for.

linkQuery Parameters

  • linklimit

    integerdefault=10

    A limit on the number of artifacts to be returned. Limit must be a number between 1 and 100.

    /v1/accounts/<account>/releases/2.0.0/artifacts?limit=25
  • linkpage

    object<string, integer>

    Object containing page size and page number. Page size must be a number between 1 and 100.

    /v1/accounts/<account>/releases/2.0.0/artifacts?page[size]=15&page[number]=2

linkReturns

A 200 OK response will be returned along with a list of artifact objects.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<id>/artifacts

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts", {
method: "GET",
headers: {
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts",
headers={
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts",
headers: [
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("artifacts", Method.GET);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Accept", "application/vnd.api+json");
 
request.AddParameter("list", 15);
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
uri_builder uri("/releases/2.0.0/artifacts");
uri.append_query("limit", 15);
 
req.set_request_uri(uri.to_uri());
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/releases/2.0.0/artifacts -g \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/vnd.api+json'

Example response / 200 OK

{
"data": [
{
"id": "0dad8516-f071-4573-bcea-d774e81c4a37",
"type": "artifacts",
"attributes": {
"filename": "install.sh",
"filetype": "sh",
"filesize": 3097,
"platform": null,
"arch": null,
"signature": "q73uw0RZ3MDooFeIUYP2iMYSWsHdL2MIhnq74IiGVEVXx0Qxeuh6eWDvlbkZ15RmjxRlTeJFjTwOubF9Hdc9Aw",
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg",
"status": "UPLOADED",
"metadata": {},
"created": "2022-05-30T13:28:01.592Z",
"updated": "2022-05-30T13:28:31.786Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"release": {
"links": {
"related": "/v1/accounts/<account>/releases/8157c656-c60f-4b82-b93f-3b3ed73abf80"
},
"data": {
"type": "releases",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
}
}
},
"links": {
"related": "/v1/accounts/<account>/releases/8157c656-c60f-4b82-b93f-3b3ed73abf80/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
"self": "/v1/accounts/<account>/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37"
}
},
]
}

linkAttach entitlement constraints

Attach entitlement constraints to a release. This will immediately be taken into effect for all future download and upgrade requests. Licenses and users must possess all entitlement constraints to be able to download or upgrade the release.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the release: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release.

linkRelationships

linkReturns

A 201 Created response will be returned along with an array of constraint objects.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>/constraints

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints", {
method: "POST",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
body: JSON.stringify({
"data": [
{
"type": "constraints",
"relationships": {
"entitlement": {
"data": { "type": "entitlements", "id": "57f1ceb4-6bf4-44dd-8967-de88364bf9eb" }
}
}
}
]
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
data=json.dumps({
"data": [
{
"type": "constraints",
"relationships": {
"entitlement": {
"data": { "type": "entitlements", "id": "57f1ceb4-6bf4-44dd-8967-de88364bf9eb" }
}
}
}
]
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints",
method: .post,
headers: [
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
],
parameters: [
"data": [
[
"type": "constraints",
"relationships": [
"entitlement": [
"data": ["type": "entitlements", "id": "57f1ceb4-6bf4-44dd-8967-de88364bf9eb"]
]
]
]
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints",
Method.POST
);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
 
request.AddJsonBody(new {
data = [
new {
type = "constraints",
relationships = new {
entitlement = new {
data = new { type = "entitlements", id = "57f1ceb4-6bf4-44dd-8967-de88364bf9eb" }
}
}
}
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to listOf(
mapOf(
"type" to "constraints",
"relationships" to mapOf(
"entitlement" to mapOf(
"data" to mapOf("type" to "entitlements", "id" to "57f1ceb4-6bf4-44dd-8967-de88364bf9eb")
)
)
)
)
))
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
import static java.util.List.of;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", of(
ofEntries(
entry("type", "constraints"),
entry("relationships", ofEntries(
entry("entitlement", ofEntries(
entry("data", ofEntries(
entry("type", "entitlements"),
entry("id", "57f1ceb4-6bf4-44dd-8967-de88364bf9eb")
))
))
))
)
))
));
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value entl_linkage;
entl_linkage["type"] = value::string("entitlements");
entl_linkage["id"] = value::string("57f1ceb4-6bf4-44dd-8967-de88364bf9eb");
 
value entl;
entl["data"] = entl_linkage;
 
value rels;
rels["entitlement"] = entl;
 
value constraint;
constraint["type"] = value::string("constraints");
constraint["relationships"] = rels;
 
value data = value::array(1);
data[0] = constraint;
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints");
req.set_method(methods::POST);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X POST https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-d '{
"data": [
{
"type": "constraints",
"relationships": {
"entitlement": {
"data": { "type": "entitlements", "id": "57f1ceb4-6bf4-44dd-8967-de88364bf9eb" }
}
}
}
]
}'

Example response / 201 Created

{
"data": [
{
"id": "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608",
"type": "constraints",
"attributes": {
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"entitlement": {
"links": {
"related": "/v1/accounts/<account>/entitlements/57f1ceb4-6bf4-44dd-8967-de88364bf9eb"
},
"data": {
"type": "entitlements",
"id": "57f1ceb4-6bf4-44dd-8967-de88364bf9eb"
}
},
"release": {
"links": {
"related": "/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827"
},
"data": {
"type": "releases",
"id": "b18e3f3a-330c-4d8d-ae2e-014db21fa827"
}
}
},
"links": {
"related": "/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints/14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
}
}
]
}

linkDetach entitlement constraints

Detach entitlement constraints from a release. This will immediately be taken into effect for all future download and upgrade requests.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the release: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release.

linkReturns

A 204 No Content response will be returned.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<release>/constraints

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints", {
method: "DELETE",
headers: {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
body: JSON.stringify({
"data": [
{
"type": "constraint",
"id": "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
}
]
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.delete(
"https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints",
headers={
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
data=json.dumps({
"data": [
{
"type": "constraint",
"id": "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
}
]
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints",
method: .delete,
headers: [
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
],
parameters: [
"data": [
[
"type": "constraint",
"id": "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
]
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints",
Method.DELETE
);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
 
request.AddJsonBody(new {
data = [
new {
type = "constraint",
id = "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
}
]
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to listOf(
mapOf(
"type" to "constraint",
"id" to "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
)
)
))
 
val res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
import static java.util.List.of;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", of(
ofEntries(
entry("type", "constraint"),
entry("id", "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608")
)
))
));
 
HttpResponse<JsonNode> res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value constraint;
constraint["type"] = value::string("constraint");
constraint["id"] = value::string("14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608");
 
value data = value::array(1);
data[0] = constraint;
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints");
req.set_method(methods::DELETE);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X DELETE https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>' \
-d '{
"data": [
{
"type": "constraint",
"id": "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
}
]
}'

Example response / 204 No Content

No Content

linkList entitlement constraints

Returns a list of entitlement constraints attached to the release. The constraints are returned sorted by creation date, with the most recent constraints appearing first.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to view the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<release>

    stringrequired

    The identifier (UUID), version or tag of the release to list constraints for.

linkQuery Parameters

  • linklimit

    integerdefault=10

    A limit on the number of constraints to be returned. Limit must be a number between 1 and 100.

    /v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints?limit=25
  • linkpage

    object<string, integer>

    Object containing page size and page number. Page size must be a number between 1 and 100.

    /v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints?page[size]=15&page[number]=2

linkReturns

A 200 OK response will be returned along with a list of constraint objects.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<id>/constraints

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints?limit=15", {
method: "GET",
headers: {
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints?limit=15",
headers={
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints?limit=15",
headers: [
"Authorization": "Bearer <token>",
"Accept": "application/vnd.api+json"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("entitlements", Method.GET);
 
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Accept", "application/vnd.api+json");
 
request.AddParameter("list", 15);
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
uri_builder uri("/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints");
uri.append_query("limit", 15);
 
req.set_request_uri(uri.to_uri());
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints?limit=15 -g \
-H 'Authorization: Bearer <token>' \
-H 'Accept: application/vnd.api+json'

Example response / 200 OK

{
"data": [
{
"id": "14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608",
"type": "constraints",
"attributes": {
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"entitlement": {
"links": {
"related": "/v1/accounts/<account>/entitlements/57f1ceb4-6bf4-44dd-8967-de88364bf9eb"
},
"data": {
"type": "entitlements",
"id": "57f1ceb4-6bf4-44dd-8967-de88364bf9eb"
}
},
"release": {
"links": {
"related": "/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827"
},
"data": {
"type": "releases",
"id": "b18e3f3a-330c-4d8d-ae2e-014db21fa827"
}
}
},
"links": {
"related": "/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/constraints/14fb3e6a-2b30-42b4-b2ff-06ca2e6c0608"
}
}
],
}

linkChange package

Change a release's package relationship. This will immediately be taken into effect for all future downloads and upgrades.

Below are the limitations to changing a release's package:

  • You cannot change to a package belonging to a different product.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the resource: either an admin, an environment, or the product it belongs to.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) or key of the release to be updated.

linkReturns

A 200 OK response will be returned along with the updated release object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/releases/<id>/package

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package", {
method: "PUT",
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
},
body: JSON.stringify({
"data": {
"type": "packages",
"id": "70af414d-6152-4ff1-892b-15a40ada6b4e"
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.put(
"https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
},
data=json.dumps({
"data": {
"type": "packages",
"id": "70af414d-6152-4ff1-892b-15a40ada6b4e"
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package",
method: .put,
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
],
parameters: [
"data": [
"type": "packages",
"id": "70af414d-6152-4ff1-892b-15a40ada6b4e"
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package",
Method.PUT
);
 
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddJsonBody(new {
data = new {
type = "packages",
id = "70af414d-6152-4ff1-892b-15a40ada6b4e"
}
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to mapOf(
"type" to "packages",
"id" to "70af414d-6152-4ff1-892b-15a40ada6b4e"
)
))
 
val res = Unirest.put("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", ofEntries(
entry("type", "packages"),
entry("id", "70af414d-6152-4ff1-892b-15a40ada6b4e")
))
));
 
HttpResponse<JsonNode> res = Unirest.put("https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value data;
data["type"] = value::string("packages");
data["id"] = value::string("70af414d-6152-4ff1-892b-15a40ada6b4e");
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package");
req.set_method(methods::PUT);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X PUT https://api.keygen.sh/v1/accounts/<account>/releases/b18e3f3a-330c-4d8d-ae2e-014db21fa827/package \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>' \
-d '{
"data": {
"type": "packages",
"id": "70af414d-6152-4ff1-892b-15a40ada6b4e"
}
}'

Example response / 200 OK

{
"data": {
"id": "ff1b4222-19d9-400b-8ffd-be5dfdadbc08",
"type": "packages",
"attributes": {
"name": "machineid",
"key": "machineid",
"engine": "pypi",
"metadata": {},
"created": "2022-05-31T14:26:09.319Z",
"updated": "2022-05-31T14:48:33.913Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
},
"product": {
"links": {
"related": "/v1/accounts/<account>/products/0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
},
"data": {
"type": "products",
"id": "0d5f0b57-3102-4ddf-beb9-f652cf8e24b7"
}
}
},
"links": {
"self": "/v1/accounts/<account>/packages/ff1b4222-19d9-400b-8ffd-be5dfdadbc08"
}
}
}