Select programming language for code examples

linkThe artifact object

Below you will find the various attributes for the artifact resource.

Artifacts can be downloaded according to the following rules:

  • Licenses: can access artifacts for their product, given the artifact was created prior to the license's expiry (if the license has an expiry), and that the license fulfills all of the release's entitlement constraints. This is typically known as a "Perpetual Fallback License."
  • Users: can access artifacts for their products, given the user has one or more associated licenses which fulfill the license requirements above.
  • Products: can access any artifact for their product.
  • Admins: can access any artifact for their account.

linkAttributes

  • linkdata.attributes.filename

    string

    The filename of the artifact. This value must be unique to the artifact's release relationship. You may include prefixes e.g. prod-1/install.sh to create an orderly directory structure, useful when distributing multiple products that need to be accessed by filename. This is just like using a file-system, organized in directories to avoid name clashes.

  • linkdata.attributes.filetype

    string

    The filetype of the artifact. This must match the filename's extension. When the filename does not contain an extension, filetype can be an arbitrary string, e.g. bin or null. When the release has multiple valid extensions, e.g. tar.gz, we recommend including the complete extension in the filetype.

  • linkdata.attributes.filesize

    integer

    The filesize of the artifact, in bytes.

  • linkdata.attributes.platform

    string

    The platform of the artifact, e.g. darwin.

  • linkdata.attributes.arch

    string

    The architecture of the artifact, e.g. amd64.

  • linkdata.attributes.status

    stringread only

    The artifact's status, indicating whether or not a file has been uploaded. Waiting and failed artifacts are unlisted. One of: WAITING, UPLOADED, or FAILED.

    An artifact will be considered failed if a file is not uploaded within 1 hour from creation date. Failed artifacts will automatically be pruned after 24 hours.
  • linkdata.attributes.signature

    string

    The signature of the artifact. This can be an arbitrary string, utilized outside of Keygen for verification purposes. For example, Keygen's CLI uses Ed25519ph signatures.

  • linkdata.attributes.checksum

    string

    The checksum of the artifact. This can be an arbitrary string, utilized outside of Keygen for verification purposes. For example, Keygen's CLI uses SHA-512 checksums.

  • linkdata.attributes.metadata

    object<string, scalar>

    Object containing artifact metadata. This can be used to store things such as additional checksums, e.g. SHA-256 and SHA-512 for integrity checks, or for notes.

  • linkdata.attributes.created

    timestamp (ISO8601 format)read only

    When the artifact was uploaded.

  • linkdata.attributes.updated

    timestamp (ISO8601 format)read only

    When the artifact was last updated.

linkRelationships

  • linkdata.relationships.account

    individual

    The account that the artifact belongs to.

  • linkdata.relationships.release

    individual

    The release that the artifact belongs to.

Example object

{
"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"
}
}
}

linkUpload an artifact

Creates a new artifact resource. Redirects to a file upload URL. The artifact will be in a WAITING status until a file is uploaded to AWS S3. If a file is not uploaded within 1 hour, the artifact will be moved to a FAILED status and automatically pruned after 24 hours.

Once a file has been uploaded to the redirect URL, the artifact's status will be changed to UPLOADED. It may take a few minutes for the status to change after the upload completes.

linkAuthentication

  • linkBearer

    required

    An authentication token with privileges to manage the resource: either an admin, or the product the artifact's release belongs to.

linkURL Parameters

  • link:account

    string, required

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

linkAttributes

  • linkdata.attributes.filename

    string, required

    The filename of the artifact. This value must be unique to the artifact's release relationship. You may include prefixes e.g. prod-1/install.sh to create an orderly directory structure, useful when distributing multiple products that need to be accessed by filename. This is just like using a file-system, organized in directories to avoid name clashes.

  • linkdata.attributes.filetype

    string, optional

    The filetype of the artifact. This must match the filename's extension. When the filename does not contain an extension, filetype can be an arbitrary string, e.g. bin or left blank. When the release has multiple valid extensions, e.g. tar.gz, we recommend including the complete extension in the filetype.

  • linkdata.attributes.filesize

    integer, optional

    The filesize of the artifact, in bytes.

  • linkdata.attributes.platform

    string, optional

    The platform of the artifact, e.g. darwin.

  • linkdata.attributes.arch

    string, optional

    The architecture of the artifact, e.g. amd64.

  • linkdata.attributes.signature

    string, optional

    The signature of the artifact. This can be an arbitrary string, utilized outside of Keygen for verification purposes. For example, Keygen's CLI uses Ed25519ph signatures.

  • linkdata.attributes.checksum

    string, optional

    The checksum of the artifact. This can be an arbitrary string, utilized outside of Keygen for verification purposes. For example, Keygen's CLI uses SHA-512 checksums.

  • linkdata.attributes.metadata

    object<string, scalar>, optional

    Object containing artifact metadata. This can be used to store things such as additional checksums, e.g. SHA-256 and SHA-512 for integrity checks, or for notes.

linkRelationships

linkReturns

A 307 Temporary Redirect status will be returned along with the new artifact object. The 303redirect will point to a file upload URL for the artifact, available in the Location header. Follow the redirect and upload the file to AWS S3.

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 PUT 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:prod-XXX, instead of the Authorization header.

To disable the redirect altogether, send a Prefer: no-redirect header, then manually follow the redirect link instead (under data.links.redirect).

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}/artifacts

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts", {
method: "POST",
headers: {
"Authorization": "Bearer {TOKEN}",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
body: JSON.stringify({
"data": {
"type": "artifact",
"attributes": {
"filename": "App-Installer.dmg",
"filesize": 209715200,
"filetype": "dmg",
"platform": "darwin",
"arch": "amd64"
},
"relationships": {
"release": {
"data": {
"type": "release",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
}
}
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer {TOKEN}"
},
data=json.dumps({
"data": {
"type": "artifact",
"attributes": {
"filename": "App-Installer.dmg",
"filesize": 209715200,
"filetype": "dmg",
"platform": "darwin",
"arch": "amd64"
},
"relationships": {
"release": {
"data": {
"type": "release",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
}
}
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts",
method: .post,
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer {TOKEN}"
],
parameters: [
"data": [
"type": "artifact",
"attributes": [
"filename": "App-Installer.dmg",
"filesize": 209715200,
"filetype": "dmg",
"platform": "darwin",
"arch": "amd64"
],
"relationships": [
"release": [
"data": [
"type": "release",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
]
]
]
]
],
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("artifacts", 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 = "artifacts",
attributes = new {
filename = "App-Installer.dmg",
filesize = 209715200,
filetype = "dmg",
platform = "darwin",
arch = "amd64"
},
relationships = new {
release = new {
data = new { type = "releases", id = "8157c656-c60f-4b82-b93f-3b3ed73abf80" }
},
}
}
});
 
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 "artifacts",
"attributes" to mapOf(
"filename" to "App-Installer.dmg",
"filesize" to 209715200,
"filetype" to "dmg",
"platform" to "darwin",
"arch" to "amd64"
),
"relationships" to mapOf(
"release" to mapOf(
"data" to mapOf("type" to "releases", "id" to "8157c656-c60f-4b82-b93f-3b3ed73abf80")
)
)
)
))
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts")
.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", "artifacts"),
entry("attributes", ofEntries(
entry("filename", "App-Installer.dmg"),
entry("filesize", 209715200),
entry("filetype", "dmg"),
entry("platform", "darwin"),
entry("arch", "amd64")
),
entry("relationships", ofEntries(
entry("release", ofEntries(
entry("data", ofEntries(
entry("type", "releases"),
entry("id", "8157c656-c60f-4b82-b93f-3b3ed73abf80")
))
))
))
))
));
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts")
.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["filename"] = value::string("App-Installer.dmg");
attrs["filesize"] = value::number(209715200);
attrs["filetype"] = value::string("dmg");
attrs["platform"] = value::string("darwin");
attrs["arch"] = value::string("amd64");
 
value product_linkage;
product_linkage["type"] = value::string("releases");
product_linkage["id"] = value::string("8157c656-c60f-4b82-b93f-3b3ed73abf80");
 
value product;
product["data"] = product_linkage;
 
value rels;
rels["release"] = product;
 
value data;
data["type"] = value::string("artifacts");
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("/artifacts");
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}/artifacts \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-d '{
"data": {
"type": "artifact",
"attributes": {
"filename": "App-Installer.dmg",
"filesize": 209715200,
"filetype": "dmg",
"platform": "darwin",
"arch": "amd64"
},
"relationships": {
"release": {
"data": {
"type": "release",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
}
}
}
}
}'

Example response / 201 Created

Location: https://keygen-dist.s3.us-east-2.amazonaws.com/artifacts/30c64dcd-a74d-4f0d-8479-8745172a4817/App-Installer.dmg?...
{
"data": {
"id": "0dad8516-f071-4573-bcea-d774e81c4a37",
"type": "artifacts",
"attributes": {
"filename": "App-Installer.dmg",
"filetype": "dmg",
"filesize": 209715200,
"platform": "darwin",
"arch": "amd64",
"signature": "q73uw0RZ3MDooFeIUYP2iMYSWsHdL2MIhnq74IiGVEVXx0Qxeuh6eWDvlbkZ15RmjxRlTeJFjTwOubF9Hdc9Aw",
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg",
"status": "WAITING",
"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}/artifacts/8157c656-c60f-4b82-b93f-3b3ed73abf80"
},
"data": {
"type": "releases",
"id": "8157c656-c60f-4b82-b93f-3b3ed73abf80"
}
}
},
"links": {
"redirect": "https://keygen-dist.s3.us-east-2.amazonaws.com/artifacts/30c64dcd-a74d-4f0d-8479-8745172a4817/App-Installer.dmg?...",
"related": "/v1/accounts/{ACCOUNT}/artifacts/8157c656-c60f-4b82-b93f-3b3ed73abf80/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
"self": "/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37"
}
}
}

linkDownload an artifact

Retrieve an artifact. This can be used to generate temporary download URLs for licensees. When the artifact has not been uploaded, or the release is not published, the endpoint will respond with a 200 OK response. When the artifact has been uploaded and the release has been published, this endpoint will respond with a 303 See Other redirect.

To download the artifact file, stored on S3, follow the redirect's Location header.

Releases can be downloaded according to the following rules:

  • Licenses: can access releases for their product, given the release was created prior to the license's expiry (if the license has an expiry), and that the license fulfills all of the release's entitlement constraints. Exact behavior will also depend on the product's distribution strategy, and the policy's expiration strategy.
  • Users: can access releases for their products, given the user has one or more associated licenses which fulfill the license requirements above.
  • Products: can access any release for their product.
  • Admins: can access any release for their account.
Use an admin or product token to generate a download link with a longer time-to-live (TTL). E.g. for use inside of a "welcome" email or on a "success" page. Use short-lived download links for "download" buttons inside of a UI portal.

In the event of a filename clash, for example, latest.yml belonging to multiple releases, the artifact for the latest version will be returned. To prevent conflicts across multiple products, we recommend using a directory structure as mentioned in the artifact filename docs, or providing a product query parameter.

You can also utilize release tags for this purpose, e.g. a app-1-latest tag, assigned to the latest version of a given product. This allows you to ensure your releases are orderly, reducing naming conflicts across products.

To only return from a certain channel, use the channel query parameter. E.g. to only pull stable releases, use ?channel=stable.

linkAuthentication

  • linkBearer

    optional

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

linkURL Parameters

  • link:account

    string, required

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

  • link:artifact

    string, required

    The identifier (UUID) or the filename of the artifact to be retrieved. If you have multiple products, we recommend adding a product-specific prefix to all release filenames in order to avoid conflicts when accessing artifacts by filename.

linkQuery Parameters

  • linkttl

    integer, optional, default is10 minutesprotectedProtected params are only available for bearers with an admin or product role.

    The time-to-live (TTL), in seconds, for the download link. The value can be between 1 minute and 1 week, in seconds. Only admins and products can set this parameter.

  • linkproduct

    string

    The identifier (UUID) the product to filter by.

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/latest.yml?product=3ab38aae-bbf7-4846-9c32-af9d94bf5ad4
  • linkchannel

    string

    The name of the channel to filter by.

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/latest.yml?channel=beta

linkReturns

When the artifact is uploaded and the release is published, 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. If the artifact is not uploaded, or the release is not published, a 200 OK status will be returned.

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.

To disable the redirect altogether, send a Prefer: no-redirect header, then manually follow the redirect link instead (under data.links.redirect).

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}/artifacts/{ARTIFACT}

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/install.sh", {
redirect: "manual",
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}/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}/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/install.sh",
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}/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}/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");
 
req.set_request_uri("/artifacts/install.sh");
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}/artifacts/install.sh \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Accept: application/vnd.api+json'

Example response / 303 See Other

Location: https://keygen-dist.s3.us-east-2.amazonaws.com/artifacts/30c64dcd-a74d-4f0d-8479-8745172a4817/install.sh?...
{
"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": {
"redirect": "https://keygen-dist.s3.us-east-2.amazonaws.com/artifacts/30c64dcd-a74d-4f0d-8479-8745172a4817/install.sh?...",
"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"
}
}
}

linkUpdate an artifact

Updates the specified artifact 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, or the product it belongs to.

linkURL Parameters

  • link:account

    string, required

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

  • link:artifact

    string, required

    The identifier (UUID) or the filename of the artifact to be retrieved. If you have multiple products, we recommend adding a product-specific prefix to all release filenames in order to avoid conflicts when accessing artifacts by filename.

linkAttributes

  • linkdata.attributes.filesize

    integer, optional

    The filesize of the artifact, in bytes.

  • linkdata.attributes.signature

    string, optional

    The signature of the artifact. This can be an arbitrary string, utilized outside of Keygen for verification purposes. For example, Keygen's CLI uses Ed25519ph signatures.

  • linkdata.attributes.checksum

    string, optional

    The checksum of the artifact. This can be an arbitrary string, utilized outside of Keygen for verification purposes. For example, Keygen's CLI uses SHA-512 checksums.

  • linkdata.attributes.metadata

    object<string, scalar>, optional

    Object containing artifact 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}/artifacts/{RELEASE}

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37", {
method: "PATCH",
headers: {
"Authorization": "Bearer {TOKEN}",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
body: JSON.stringify({
"data": {
"type": "artifacts",
"attributes": {
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg"
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.patch(
"https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
headers={
"Authorization": "Bearer {TOKEN}",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
data=json.dumps({
"data": {
"type": "artifacts",
"attributes": {
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg"
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
method: .patch,
headers: [
"Authorization": "Bearer {TOKEN}",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
],
parameters: [
"data": [
"type": "artifacts",
"attributes": [
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg"
]
]
],
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(
"artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
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 = "artifacts",
attributes = new {
checksum = "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg"
}
}
});
 
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 "artifacts",
"attributes" to mapOf(
"checksum" to "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg"
)
)
))
 
val res = Unirest.patch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37")
.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", "artifacts"),
entry("attributes", ofEntries(
entry("checksum", "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg")
))
))
));
 
HttpResponse<JsonNode> res = Unirest.patch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37")
.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["checksum"] = value::string("l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg");
 
value data;
data["type"] = value::string("artifacts");
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("/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37");
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}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37 \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-d '{
"data": {
"type": "artifacts",
"attributes": {
"checksum": "l7PETeny2BRIC4T7tC1w0dLOeR0ghWtDJZw3GIuIK9LEdSKRZKda7iWJVkH9KhDSroPunsAAJ1T14UB88MFiBg"
}
}
}'

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

linkYank an artifact

Queues the artifact and its files to be permanently deleted. It cannot be undone. If you need to yank an entire release, 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, the product it belongs to.

linkURL Parameters

  • link:account

    string, required

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

  • link:artifact

    string, required

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

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}/artifacts/{ARTIFACT}

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37", {
method: "DELETE",
headers: {
"Authorization": "Bearer {TOKEN}",
"Accept": "application/vnd.api+json"
}
})
import requests
 
res = requests.delete(
"https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
headers={
"Authorization": "Bearer {TOKEN}",
"Accept": "application/vnd.api+json"
}
)
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
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(
"artifacts/0dad8516-f071-4573-bcea-d774e81c4a37",
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}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37")
.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}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37")
.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("/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37");
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}/artifacts/0dad8516-f071-4573-bcea-d774e81c4a37 \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Accept: application/vnd.api+json'

Example response / 204 No Content

No content

linkList all artifacts

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

linkAuthentication

  • linkBearer

    optional

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

linkURL Parameters

  • link:account

    string, required

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

linkFilters

  • linklimit

    integer, default is10

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

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?limit=25
  • linkpage

    object<string, integer>

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

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?page[size]=15&page[number]=2
  • linkproduct

    string

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

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?product=3ab38aae-bbf7-4846-9c32-af9d94bf5ad4
  • linkrelease

    string

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

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?release=8157c656-c60f-4b82-b93f-3b3ed73abf80
  • linkchannel

    string

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

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?channel=beta
  • linkfiletype

    string

    The identifier (UUID) or name of the filetype to filter by.

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?filetype=zip
  • linkplatform

    string

    The identifier (UUID) or name of the platform to filter by.

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?platform=darwin
  • linkarch

    string

    The identifier (UUID) or name of the arch to filter by.

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?arch=amd64
  • linkstatus

    string

    The status to filter by.

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?status=WAITING

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}/artifacts{FILTERS}

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/artifacts?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}/artifacts?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}/artifacts?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("artifacts", Method.GET);
 
request.AddHeader("Authorization", "Bearer {TOKEN}");
request.AddHeader("Accept", "application/vnd.api+json");
 
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}/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}/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("/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}/artifacts?limit=15 -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"
}
}
]
}