Select programming language for code examples

linkMetadata

Many resources including products, users, licenses, machines and policies have a metadata attribute. You can use this attribute to attach key-value data to the given resource.

Metadata is useful for storing additional, structured information on an object. As an example, you could store your user's zipcode, their id within your own database (if applicable), or their Stripe customer_id for billing purposes.

Since the metadata attribute is simply a key-value store (object), all write operations will overwrite the entire object, so be sure to merge existing data on your end when performing updates.

Do not attach sensitive billing information directly to resources using the metadata attribute. Doing so is a violation of our terms of use. If you're using Stripe, you need only attach their Stripe customer_id, or a temporary secure representation of a card (such as a stripe_token), which can then be used to look up their information server-side when required.

You may specify up to 64 metadata keys, with key names up to 256 characters in length and with values up to 512 characters in length.

Key Transformation

Please note: all keys will be transformed into lower camelcase (exampleKey), so we recommend using lower camelcase when possible. For example, example_key will be transformed into exampleKey, ExampleKey will also be transformed into exampleKey, etc.

Example Use Cases

Here's a few example metadata use cases:

Use Case
Link IDs Attach your system's unique IDs to a Keygen object, for easy lookups. For example, add an order number for a license, Stripe customer and subscription IDs, or the customer's user ID in your system.
License entitlements Store information about what features or actions a license is allowed to perform.
Customer details Annotate a user by storing additional details such as company name for later use.

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298", {
method: "PATCH",
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer {TOKEN}"
},
body: JSON.stringify({
"data": {
"type": "licenses",
"attributes": {
"metadata": {
"customerEmail": "[email protected]",
"customerId": "cust_a7e3ca415298f0",
"isPro": true
}
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.patch(
"https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer {TOKEN}"
},
data=json.dumps({
"data": {
"type": "licenses",
"attributes": {
"metadata": {
"customerEmail": "[email protected]",
"customerId": "cust_a7e3ca415298f0",
"isPro": true
}
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298",
method: .patch,
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer {TOKEN}"
],
parameters: [
"data": [
"type": "licenses",
"attributes": [
"metadata": [
"customerEmail": "[email protected]",
"customerId": "cust_a7e3ca415298f0",
"isPro": true
]
]
]
],
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(
"licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298",
Method.PATCH
);
 
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 = "licenses",
attributes = new {
metadata = new {
customerEmail = "[email protected]",
customerId = "cust_a7e3ca415298f0",
isPro = true
}
}
}
});
 
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 "licenses",
"attributes" to mapOf(
"metadata" to mapOf(
"customerEmail" to "[email protected]",
"customerId" to "cust_a7e3ca415298f0",
"isPro" to true
)
)
)
))
 
val res = Unirest.patch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298")
.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", "licenses"),
entry("attributes", ofEntries(
entry("metadata", ofEntries(
entry("customerEmail", "[email protected]"),
entry("customerId", "cust_a7e3ca415298f0"),
entry("isPro", true)
))
))
))
));
 
HttpResponse<JsonNode> res = Unirest.patch("https://api.keygen.sh/v1/accounts/{ACCOUNT}/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298")
.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 metadata;
metadata["customerEmail"] = value::string("[email protected]");
metadata["customerId"] = "cust_a7e3ca415298f0";
metadata["isPro"] = true;
 
value attrs;
attrs["metadata"] = metadata;
 
value data;
data["type"] = value::string("licenses");
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("/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298");
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}/licenses/a5a154d2-f026-40fa-bc8d-a7e3ca415298 \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer {TOKEN}' \
-d '{
"data": {
"type": "licenses",
"attributes": {
"metadata": {
"customerEmail": "[email protected]",
"customerId": "cust_a7e3ca415298f0",
"isPro": true
}
}
}
}'