Skip to content

Create a user certificate request

POST
/api/certs/user
curl --request POST \
--url https://example.com/api/certs/user \
--header 'Content-Type: application/json' \
--data '{}'

Unauthenticated. Returns two relative URLs: events_url to wait on, and approval_url for a human to open. The request ID is the capability — it is an unguessable UUID, and holding it is what authorizes waiting on the outcome.

The public key to sign, and the options being asked for

Media typeapplication/json
One of:
object

Example generated

{}

Request created

Media typeapplication/json
object
data
required
object
approval_url
required
string
events_url
required
string
expires_at

ExpiresAt is when this request stops being approvable, from its own type’s budget (cert_options..client_timeout, falling back to cert_options.client_timeout). Populated for every type.

A client bounds its wait by this rather than by a local guess, and a console displays the time remaining from it. Without it, the client’s timeout and the server’s budget are two numbers an operator keeps in agreement by hand, and disagreement surfaces as a client still waiting on a request the server already killed. RFC 8628 carries expires_in for the same reason.

string
request_id
required
string
user_code

UserCode is the short code a human types into the web UI, grouped for display (“K7M4-QP2X”). Console requests only; empty for every other type, so no existing consumer changes.

This is the only response it ever appears in. It is not in the SSE stream, not in the request detail, and not in any audit record.

string
verification_url

VerificationURL is the page that accepts UserCode; VerificationURLComplete embeds the code so a device with a camera or a keyboard can skip the code box entirely. Relative, like the two URLs above, and console requests only.

Complete is kept short (/c/, not /approve/) because it is what a QR code drawn in an 80x24 terminal has to encode.

string
verification_url_complete
string
error
string

Example generated

{
"data": {
"approval_url": "example",
"events_url": "example",
"expires_at": "example",
"request_id": "example",
"user_code": "example",
"verification_url": "example",
"verification_url_complete": "example"
},
"error": "example"
}

Malformed body, or a public key that will not parse

Media typeapplication/json
object
data

Data is always null on an error response.

error
required

Error is a human-readable message. Branch on the HTTP status rather than this string; it is for humans and logs.

string
error_code
required

ErrorCode is a machine-readable error classifier. One of the error_code constants from internal/apitypes; use this to decide whether to retry or branch on the failure mode.

string

Example

{
"error": "certificate request \"9f1c…\" not found",
"error_code": "not_found"
}