Skip to content

`POST /v1/orgs/{org}/enrollment-tokens`.

POST
/v1/orgs/{org}/enrollment-tokens
curl --request POST \
--url https://api.updawg.net/v1/orgs/example/enrollment-tokens \
--header 'Content-Type: application/json' \
--data '{ "expires_at": "2026-04-15T12:00:00Z", "labels": { "additionalProperty": "example" }, "max_uses": 1, "name": "example" }'
org
required
string

Organization slug.

Media typeapplication/json
object
expires_at

When it stops working. Absent never expires.

string | null format: date-time
labels

Put on every host that enrols with it.

object
key
additional properties
string
max_uses

How many hosts it may enrol. Absent is unlimited.

integer | null format: int32
name
required

What it is for — “web tier”, “laptop test”. Shown in the list, since the value never is again.

string
Examplegenerated
{
"expires_at": "2026-04-15T12:00:00Z",
"labels": {
"additionalProperty": "example"
},
"max_uses": 1,
"name": "example"
}

Issued. ⚠️ token is in this response and never again.

Media typeapplication/json

The one response that carries the value.

object
created_at
required
string format: date-time
expires_at
string | null format: date-time
id
required

etk_…. The record, not the credential.

string
labels
required
object
key
additional properties
string
max_uses
integer | null format: int32
name
required
string
revoked_at
string | null format: date-time
usable
required

Whether an agent presenting it now would be let in: not revoked, not expired, not used up. The same three conditions the gateway checks, so the portal does not have to know them.

boolean
uses
required

Hosts that enrolled with it and then checked in. A use is charged on the first check-in, not when the certificate is issued, so an attempt the agent refused costs nothing (DAWG-224).

integer format: int32
token
required

⚠️ Shown once. enr_…. Only its hash is kept.

string
Examplegenerated
{
"created_at": "2026-04-15T12:00:00Z",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"labels": {
"additionalProperty": "example"
},
"max_uses": 1,
"name": "example",
"revoked_at": "2026-04-15T12:00:00Z",
"usable": true,
"uses": 1,
"token": "example"
}

No name, a limit below one, an expiry in the past, or labels that are not a small map of non-empty keys.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

No session.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

Not permitted for this role.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

No such organization, or not yours — one answer for both.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

Over the organization’s request limit. Retry-After says when to try again; RateLimit-Limit is the burst.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}