Harthelm Docs
REST APIDomains

Add a custom domain

Team admins (`team.manage`). The domain is unverified until a check finds its TXT record `_harthelm.<name>` (the record of purpose `verification`; a CNAME or A record only routes and never proves ownership); only a verified domain gets an edge object, a certificate and traffic. An unverified domain is a claim that expires: at `expires_at` (`customDomains.claimDays` after its creation, 7 by default) it is removed and the name is free again. 409 `domain-taken` when any team has the name, `domain-reserved` for the console host and names under the workspace domain, `domain-limit` when the team has `customDomains.maxPerTeam` domains; 409 `custom-domains-disabled` when the installation has none; 429 `domain-create-rate` (with `Retry-After`) when the team added `customDomains.createPerTeamPerHour` domains in the last hour (each verified domain costs an ACME order on the installation's shared account).

Generated from openapi/harthelm.yaml at v1.5.0
POST
/teams/{team}/domains

Authorization

cookie__Host-harthelm_session<token>

Browser session of the UI (12 h idle, 7 days absolute). State-changing requests also need the header Harthelm-CSRF: 1 and a matching Origin.

Path Parameters

team*integer

Numeric resource id.

Formatint64
Range1 <= value

Header Parameters

Idempotency-Key?string

Client-chosen key (at most 255 characters); a repeated key returns the first result for 24 h.

Length1 <= length <= 255

Request Body

application/json
  1. body
name*DomainNameValue

A host name of at least two labels (letters, digits, hyphens; IDNs in their xn-- form), compared in lower case; no wildcard, no IP address, no trailing dot.

Length3 <= length <= 253
restricted?boolean

Only team members (signed in through the domain hop, or with an API key) reach the domain.

Defaultfalse

Response Body

The domain.

application/json
  1. response
id*string
Formatuuid
team_id*ID

Numeric resource id.

Formatint64
Range1 <= value
name*DomainNameValue

A host name of at least two labels (letters, digits, hyphens; IDNs in their xn-- form), compared in lower case; no wildcard, no IP address, no trailing dot.

Length3 <= length <= 253
url*string

The domain's HTTPS URL, from its name.

restricted*boolean
use_regex*boolean
max_body_bytes*integer

The effective limit (the installation default when none is set).

Formatint64
timeout_seconds*integer

The effective limit.

verification*
tls*
records*array<>

The DNS records to set, in the order the console shows them.

routes*array<>
created_by?ID

Numeric resource id.

Formatint64
Range1 <= value
created_at*string
Formatdate-time
updated_at*string
Formatdate-time
expires_at?string

An unverified domain (never verified): when the claim is released and the domain removed (its creation plus customDomains.claimDays). Absent once verified, and from an older core.

Formatdate-time
curl -X POST 'https://console.example.com/api/v1/teams/1/domains' \  -H 'Content-Type: application/json' \  -d '{  "name": "string"}'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "team_id": 1,  "name": "string",  "url": "string",  "restricted": true,  "use_regex": true,  "max_body_bytes": 0,  "timeout_seconds": 0,  "verification": {    "status": "unchecked",    "method": "txt",    "checked_at": "2019-08-24T14:15:22Z",    "verified_at": "2019-08-24T14:15:22Z",    "reason": "string",    "txt_missing_since": "2019-08-24T14:15:22Z",    "lapses_at": "2019-08-24T14:15:22Z"  },  "tls": {    "mode": "automated",    "status": "pending",    "reason": "string",    "not_after": "2019-08-24T14:15:22Z",    "covered_by": "string"  },  "records": [    {      "type": "CNAME",      "name": "string",      "value": "string",      "purpose": "verification"    }  ],  "routes": [    {      "path": "string",      "workspace_ids": [        1      ]    }  ],  "created_by": 1,  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z"}