Upload a custom extension
const url = 'http://localhost:8000/extensions';
const form = new FormData();
form.append('jar', 'file');
form.append('metadata', '{ "name": "example", "description": "example", "keycloak_version": "example", "version": "example", "parameter_type": "env", "parameters": [ { "key": "example", "label": "example", "type": "text", "required": true, "default_value": "example", "options": [ { "value": "example", "label": "example" } ], "is_sensitive": true } ], "repository_url": "https://example.com", "icon_url": "https://example.com" }');
const options = {
method: 'POST',
headers: {'API-Version': '2026-06-01.beta', 'API-Key': '<API-Key>'}
};
options.body = form;
try {
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}curl --request POST \
--url http://localhost:8000/extensions \
--header 'API-Key: <API-Key>' \
--header 'API-Version: 2026-06-01.beta' \
--header 'Content-Type: multipart/form-data' \
--form jar=@file \
--form 'metadata={ "name": "example", "description": "example", "keycloak_version": "example", "version": "example", "parameter_type": "env", "parameters": [ { "key": "example", "label": "example", "type": "text", "required": true, "default_value": "example", "options": [ { "value": "example", "label": "example" } ], "is_sensitive": true } ], "repository_url": "https://example.com", "icon_url": "https://example.com" }'Uploads a new custom extension JAR to the workspace. The JAR is asynchronously scanned for malware;
poll the returned extension’s scan_status until it reaches ready before installing on a cluster.
Maximum body size is 150 MB.
Required scope: extensions:write
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
JAR file containing the Keycloak extension. Content type must be application/java-archive.
Extension metadata and parameter schema.
object
Keycloak major version this JAR targets (e.g. "26").
Semantic version string (e.g. "1.0.0"). Defaults to 1.0.0.
object
object
Responses
Section titled “Responses”The request has succeeded and a new resource has been created as a result.
object
Friendly name shown in place of name when set. name never changes once an extension is catalogued; display_name lets the shown label change independently. Absent or null when the extension has none, in which case clients should fall back to name.
Set for platform extensions only: private marks an early-access extension your workspace has been granted. Absent for custom extensions.
Active version of the extension. For platform extensions this is the newest release across its supported Keycloak versions; the version a given cluster gets is available_version on its cluster extension. For custom extensions it is the uploader-supplied version.
Previously published versions, ordered from oldest to newest.
object
Supported Keycloak major versions (e.g. ["25", "26"]).
object
Unique parameter identifier within the extension.
Available choices. Only applicable when type is dropdown.
object
When true, the parameter value is write-only and omitted from read responses.
Malware scan result. Only set for custom extensions.
Human-readable scan result. Present when scan_status is rejected (names the detected signature) or failed (says the scan could not complete).
Original JAR filename provided at upload time. Only set for custom extensions.
JAR file size in bytes. Only set for custom extensions.
When the extension was first uploaded. Only set for custom extensions.
Example
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Social Login Bundle",
"description": "Adds social login providers for Google, GitHub, and Microsoft.",
"source": "platform",
"version": "3.1.0",
"previous_versions": [],
"keycloak_versions": [
"25",
"26"
],
"parameter_type": "env",
"parameters": [],
"repository_url": null,
"icon_url": null,
"documentation_url": null,
"quick_start_steps": null,
"usage_notes": null,
"scan_status": null,
"scan_message": null,
"original_jar_name": null,
"file_size_bytes": null,
"uploaded_at": "2025-01-15T10:00:00Z",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-03-20T14:30:00Z"
}The server could not understand the request due to invalid syntax.
RFC 9457 Problem Details object.
object
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com"
}Access is unauthorized.
RFC 9457 Problem Details object.
object
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com"
}Client error
Returned when a workspace plan quota would be exceeded. required_plan indicates the minimum plan needed to complete the request.
object
Machine-readable identifier of the quota that was hit, so a client can tell
quotas apart without parsing detail. Known values include cluster_limit
(the workspace’s total cluster allowance), cluster_size_quota (the
allowance for the requested cluster size) and cluster_size (the requested
size is not offered on the plan at all). New values may be added.
How many of the resource the workspace currently has.
Maximum allowed by the current plan. 0 means the plan does not include the resource at all.
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com",
"current_plan": "example",
"required_plan": "example",
"code": "example",
"current_usage": 1,
"current_limit": 1
}Client error
object
object
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com",
"errors": [
{
"field": "example",
"detail": "example",
"code": "example",
"value": "example"
}
]
}Client error
RFC 9457 Problem Details object.
object
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com"
}Headers
Section titled “Headers”Server error
RFC 9457 Problem Details object.
object
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com"
}Server error
RFC 9457 Problem Details object.
object
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"instance": "https://example.com"
}