Skip to content

Create join key

POST
/v1/join-keys

Create a join key: a reusable enrollment code that any number of machines can enroll with, each joining as a new host with the key’s network, role, and tags. Enroll a machine by passing the returned token to dnclient enroll -code.

The token is only returned by this request, so store it somewhere safe.

Returns ERR_LIMIT_EXCEEDED if the organization has reached its join key limit.

Token scope required: join-keys:create

object
name
required

Identifies the key, and names hosts that enroll without reporting a usable hostname. Must be a DNS label: lowercase letters, digits, and hyphens, not starting or ending with a hyphen. Must be unique within the organization.

string
>= 1 characters <= 54 characters /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/
Example
ci-runner
networkID
required

Network that hosts enrolled with this key join. Can’t be changed later.

string
Example
network-KAOWMXZHZWCVMGGFKM22XEGYLE
roleID

Role assigned to hosts enrolled with this key. Can’t be changed later.

string | null
Example
role-PZEDBXHCEXKAKJPZ6XOQTIAJA4
tags

Tags assigned to hosts enrolled with this key. Can’t be changed later.

array | null
Example
[
"env:ci"
]
autoAssignCIDRs

Prefixes from which hosts enrolled with this key are assigned addresses. Each must exactly match the network’s IPv4 CIDR or IPv6 prefix. On a network with an IPv6 prefix, that prefix is always included even if omitted here, so list the IPv4 CIDR to also give enrolled hosts an IPv4 address. Can’t be changed later.

array | null
<= 2 items
Example
[
"100.100.0.0/22"
]
expiresAt

When the key stops enrolling hosts. Must be in the future. Omit for a key that does not expire.

string | null format: date-time
Example
2027-01-01T00:00:00Z
Example
{
"name": "ci-runner",
"networkID": "network-KAOWMXZHZWCVMGGFKM22XEGYLE",
"roleID": "role-PZEDBXHCEXKAKJPZ6XOQTIAJA4",
"tags": [
"env:ci"
],
"autoAssignCIDRs": [
"100.100.0.0/22"
],
"expiresAt": "2027-01-01T00:00:00Z"
}

Successful operation

object
data
required
object
id
required
string
Example
dnjoin-P3RCTXN5LVFGBMJNYF2QHKWDOA
organizationID
required
string
Example
org-F63A24JGCLJV3ZEUTLCBISGETA
name
required

Identifies the key. Hosts that enroll without reporting a usable hostname are named after it, followed by a random suffix.

string
Example
ci-runner
networkID
required

Network that hosts enrolled with this key join.

string
Example
network-KAOWMXZHZWCVMGGFKM22XEGYLE
roleID
required

Role assigned to hosts enrolled with this key.

string | null
Example
role-PZEDBXHCEXKAKJPZ6XOQTIAJA4
tags
required

Tags assigned to hosts enrolled with this key.

Array<string>
Example
[
"env:ci"
]
autoAssignCIDRs
required

Prefixes from which hosts enrolled with this key are assigned addresses. Includes the network’s IPv6 prefix whenever the network has one.

array | null
Example
[
"100.100.0.0/22",
"fdef:c0:c0:1::/80"
]
expiresAt
required

When the key stops enrolling hosts. null means the key does not expire.

string | null format: date-time
Example
2027-01-01T00:00:00Z
createdAt
required
string format: date-time
Example
2026-10-29T15:00:00Z
modifiedAt
required
string format: date-time
Example
2026-10-29T15:00:00Z
token
required

The token machines enroll with. Only returned when the key is created.

string
Example
dnjoin-P3RCTXN5LVFGBMJNYF2QHKWDOA-6YQKZ3VNB2XGJ4MEPLRT7WCSAHDUF5IO3QXBKZNYV2MJ4RLEHGTA
Example
{
"data": {
"id": "dnjoin-P3RCTXN5LVFGBMJNYF2QHKWDOA",
"organizationID": "org-F63A24JGCLJV3ZEUTLCBISGETA",
"name": "ci-runner",
"networkID": "network-KAOWMXZHZWCVMGGFKM22XEGYLE",
"roleID": "role-PZEDBXHCEXKAKJPZ6XOQTIAJA4",
"tags": [
"env:ci"
],
"autoAssignCIDRs": [
"100.100.0.0/22",
"fdef:c0:c0:1::/80"
],
"expiresAt": "2027-01-01T00:00:00Z",
"createdAt": "2026-10-29T15:00:00Z",
"modifiedAt": "2026-10-29T15:00:00Z",
"token": "dnjoin-P3RCTXN5LVFGBMJNYF2QHKWDOA-6YQKZ3VNB2XGJ4MEPLRT7WCSAHDUF5IO3QXBKZNYV2MJ4RLEHGTA"
}
}

Validation error

object
errors
required
Array<object>
object
code
required

A static name for the error type

string
message
required

A short human readable description of the error

string
path

Describes the variable missing or malformed

string
param

The query parameter the error relates to, such as filter.targetType

string
extra

Machine-readable details about the error. ERR_LIMIT_EXCEEDED errors carry limit and limitName.

object
limit

The maximum number of resources allowed

integer
limitName

The kind of resource the limit applies to

string
key
additional properties
any
Examples

A join key already exists with the name.

{
"errors": [
{
"code": "ERR_DUPLICATE_VALUE",
"message": "value already exists",
"path": "name"
}
]
}

The API key is missing, invalid or expired.

object
errors
required
Array<object>
object
code
required

A static name for the error type

string
message
required

A short human readable description of the error

string
path

Describes the variable missing or malformed

string
param

The query parameter the error relates to, such as filter.targetType

string
extra

Machine-readable details about the error. ERR_LIMIT_EXCEEDED errors carry limit and limitName.

object
limit

The maximum number of resources allowed

integer
limitName

The kind of resource the limit applies to

string
key
additional properties
any
Example
{
"errors": [
{
"code": "ERR_UNAUTHORIZED",
"message": "unauthorized"
}
]
}

The API key lacks a required scope.

object
errors
required
Array<object>
object
code
required

A static name for the error type

string
message
required

A short human readable description of the error

string
path

Describes the variable missing or malformed

string
param

The query parameter the error relates to, such as filter.targetType

string
extra

Machine-readable details about the error. ERR_LIMIT_EXCEEDED errors carry limit and limitName.

object
limit

The maximum number of resources allowed

integer
limitName

The kind of resource the limit applies to

string
key
additional properties
any
Examples

The API key lacks a required scope.

{
"errors": [
{
"code": "ERR_FORBIDDEN",
"message": "api key must support the following scopes: hosts:read"
}
]
}

The organization has exceeded its API request rate limit. Retry the request after a short delay.

object
errors
required
Array<object>
object
code
required

A static name for the error type

string
message
required

A short human readable description of the error

string
path

Describes the variable missing or malformed

string
param

The query parameter the error relates to, such as filter.targetType

string
extra

Machine-readable details about the error. ERR_LIMIT_EXCEEDED errors carry limit and limitName.

object
limit

The maximum number of resources allowed

integer
limitName

The kind of resource the limit applies to

string
key
additional properties
any
Example
{
"errors": [
{
"code": "ERR_TOO_MANY_REQUESTS",
"message": "too many requests"
}
]
}