White label

Brand the dashboard with your name, colour and logo, serve it on your own domain and use your own name servers.

On this page

White label lets an agency show the dashboard and its emails with its own brand, serve the dashboard on its own domain (a CNAME to custom.openwaf.dev) and publish its zones with its own name servers. These routes have no SDK methods yet; the examples use curl.

OperationEndpoint
Get brandGET /v1/orgs/{org}/brand
Set brandPUT /v1/orgs/{org}/brand
Get brand logoGET /v1/orgs/{org}/brand/logo
Upload brand logoPUT /v1/orgs/{org}/brand/logo
Delete brand logoDELETE /v1/orgs/{org}/brand/logo
Get dashboard domainGET /v1/orgs/{org}/whitelabel/domain
Set dashboard domainPUT /v1/orgs/{org}/whitelabel/domain
Delete dashboard domainDELETE /v1/orgs/{org}/whitelabel/domain
Verify dashboard domainPOST /v1/orgs/{org}/whitelabel/domain/verify
Get own name serversGET /v1/orgs/{org}/whitelabel/nameservers
Set own name serversPUT /v1/orgs/{org}/whitelabel/nameservers
Delete own name serversDELETE /v1/orgs/{org}/whitelabel/nameservers
Verify own name serversPOST /v1/orgs/{org}/whitelabel/nameservers/verify

Get brand

GET /v1/orgs/{org}/brand

Returns the brand of the organization (name, accent colour, logo and support email). Without a brand of its own, the answer is the OpenWAF brand (org_id null).

Required role: readonly or higher.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

FieldTypeDescription
org_idstring (uuid) or nullOrganization of the brand; null = the OpenWAF brand.
namestringName.
logo_urlstring or nullURL of the logo in the dashboard, versioned by its content; null without a logo.
accentstringAccent colour #rrggbb.
support_emailstring
oauthbooleanWhether the dashboard on this domain offers Google and GitHub sign-in (only the OpenWAF domain).

Errors

StatusDescription
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/brand" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "org_id": "1e7c9a3b-5d2f-4b8a-9c6e-0f2a4b6c8d1e",
  "name": "example.com",
  "logo_url": "/v1/brand/logo?v=3f9a1c2b7d4e",
  "accent": "#0f766e",
  "support_email": "[email protected]",
  "oauth": false
}

Set brand

PUT /v1/orgs/{org}/brand

Sets the name, accent colour and support email that the dashboard and its emails show for the organization.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Request body

Content type application/json. Schema: BrandInput.

FieldTypeRequiredDescription
namestringYesName shown by the dashboard and the emails; no line breaks, < or >. At most 100 characters.
accentstringYesAccent colour #rrggbb (lowercased). Pattern ^#[0-9a-f]{6}$.
support_emailstring (email)NoSupport email shown by the dashboard and the emails.

Response

FieldTypeDescription
org_idstring (uuid) or nullOrganization of the brand; null = the OpenWAF brand.
namestringName.
logo_urlstring or nullURL of the logo in the dashboard, versioned by its content; null without a logo.
accentstringAccent colour #rrggbb.
support_emailstring
oauthbooleanWhether the dashboard on this domain offers Google and GitHub sign-in (only the OpenWAF domain).

Errors

StatusDescription
400Malformed request (bad_request).
403The token's role or limits do not allow it (forbidden).
422Validation error (invalid).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X PUT "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/brand" \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "Acme Digital",
    "accent": "#0f766e",
    "support_email": "[email protected]"
  }'
200
{
  "org_id": "1e7c9a3b-5d2f-4b8a-9c6e-0f2a4b6c8d1e",
  "name": "example.com",
  "logo_url": "/v1/brand/logo?v=3f9a1c2b7d4e",
  "accent": "#0f766e",
  "support_email": "[email protected]",
  "oauth": false
}
GET /v1/orgs/{org}/brand/logo

Returns the logo of the brand as image/svg+xml or image/png.

Required role: readonly or higher.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

  • 200: The logo. Body of type image/png.

Errors

StatusDescription
404Not found, or not visible to the token (not_found).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/brand/logo" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
PUT /v1/orgs/{org}/brand/logo

Uploads the logo as the raw request body, image/svg+xml or image/png, up to 256 KB (PNG up to 4096×4096 pixels). Set the brand with Set brand first.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Request body

Content type image/png.

At most 262144 characters.

Response

FieldTypeDescription
org_idstring (uuid) or nullOrganization of the brand; null = the OpenWAF brand.
namestringName.
logo_urlstring or nullURL of the logo in the dashboard, versioned by its content; null without a logo.
accentstringAccent colour #rrggbb.
support_emailstring
oauthbooleanWhether the dashboard on this domain offers Google and GitHub sign-in (only the OpenWAF domain).

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
422invalid: not a valid SVG or PNG, larger than 256 KB or 4096×4096 pixels, or the brand has no name and colour yet.
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X PUT "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/brand/logo" \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: image/png" \
  --data-binary @logo.png
200
{
  "org_id": "1e7c9a3b-5d2f-4b8a-9c6e-0f2a4b6c8d1e",
  "name": "example.com",
  "logo_url": "/v1/brand/logo?v=3f9a1c2b7d4e",
  "accent": "#0f766e",
  "support_email": "[email protected]",
  "oauth": false
}
DELETE /v1/orgs/{org}/brand/logo

Removes the logo of the brand.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

FieldTypeDescription
org_idstring (uuid) or nullOrganization of the brand; null = the OpenWAF brand.
namestringName.
logo_urlstring or nullURL of the logo in the dashboard, versioned by its content; null without a logo.
accentstringAccent colour #rrggbb.
support_emailstring
oauthbooleanWhether the dashboard on this domain offers Google and GitHub sign-in (only the OpenWAF domain).

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/brand/logo" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "org_id": "1e7c9a3b-5d2f-4b8a-9c6e-0f2a4b6c8d1e",
  "name": "example.com",
  "logo_url": "/v1/brand/logo?v=3f9a1c2b7d4e",
  "accent": "#0f766e",
  "support_email": "[email protected]",
  "oauth": false
}

Get dashboard domain

GET /v1/orgs/{org}/whitelabel/domain

Returns the organization's own dashboard domain and its status.

Required role: readonly or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

FieldTypeDescription
hoststringOwn domain of the dashboard, e.g. panel.example.com.
statusstringOne of pending, active, error.
detailstringReason of the error status (empty if none).
cname_targetstringTarget of the CNAME record to create (not proxied).
checked_atstring (date-time)Last check.
activated_atstring (date-time)When the zone became active.

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
404not_found: the organization has no own domain.
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/domain" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "host": "www.example.com",
  "status": "pending",
  "detail": "",
  "cname_target": "custom.openwaf.dev",
  "checked_at": "2026-10-27T09:30:00Z",
  "activated_at": "2026-10-27T09:30:00Z"
}

Set dashboard domain

PUT /v1/orgs/{org}/whitelabel/domain

Sets the domain on which the dashboard is served with the organization's brand. It starts pending. Create a CNAME record from that name to cname_target (custom.openwaf.dev, DNS only, not proxied) and then call Verify dashboard domain. Changing the domain stops serving the previous one.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Request body

Content type application/json.

FieldTypeRequiredDescription
hoststringYesOwn domain of the dashboard, e.g. panel.example.com.

Response

FieldTypeDescription
hoststringOwn domain of the dashboard, e.g. panel.example.com.
statusstringOne of pending, active, error.
detailstringReason of the error status (empty if none).
cname_targetstringTarget of the CNAME record to create (not proxied).
checked_atstring (date-time)Last check.
activated_atstring (date-time)When the zone became active.

Errors

StatusDescription
400Malformed request (bad_request).
403The token's role or limits do not allow it (forbidden).
409host_taken: the name belongs to another organization.
422Validation error (invalid).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X PUT "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/domain" \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "host": "panel.acme.example"
  }'
200
{
  "host": "www.example.com",
  "status": "pending",
  "detail": "",
  "cname_target": "custom.openwaf.dev",
  "checked_at": "2026-10-27T09:30:00Z",
  "activated_at": "2026-10-27T09:30:00Z"
}

Delete dashboard domain

DELETE /v1/orgs/{org}/whitelabel/domain

Removes the organization's own dashboard domain; the dashboard stops being served on it.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

  • 204: Deleted. No body.

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
404Not found, or not visible to the token (not_found).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/domain" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"

Verify dashboard domain

POST /v1/orgs/{org}/whitelabel/domain/verify

Checks the CNAME record of the dashboard domain. When it points to cname_target the domain becomes active and the dashboard is served on it with a certificate; otherwise the status is error and detail says what to fix.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

FieldTypeDescription
hoststringOwn domain of the dashboard, e.g. panel.example.com.
statusstringOne of pending, active, error.
detailstringReason of the error status (empty if none).
cname_targetstringTarget of the CNAME record to create (not proxied).
checked_atstring (date-time)Last check.
activated_atstring (date-time)When the zone became active.

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
404Not found, or not visible to the token (not_found).
409host_taken: the name belongs to another organization.
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X POST "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/domain/verify" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "host": "www.example.com",
  "status": "pending",
  "detail": "",
  "cname_target": "custom.openwaf.dev",
  "checked_at": "2026-10-27T09:30:00Z",
  "activated_at": "2026-10-27T09:30:00Z"
}

Get own name servers

GET /v1/orgs/{org}/whitelabel/nameservers

Returns the organization's own name servers, their status, the addresses they must resolve to and the ownership TXT records.

Required role: readonly or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

FieldTypeDescription
nsarray of stringThe two own name servers.
statusstringOne of pending, active, error.
detailstringReason of the error status (empty if none).
required_ipsobjectAddresses both names must resolve to exactly (A and AAAA).
required_ips.v4array of string
required_ips.v6array of string
ownership_txtarray of objectTXT records proving that the organization controls the domain of its name servers; verification requires them before activation.
ownership_txt[].namestringName.
ownership_txt[].valuestring
checked_atstring (date-time)Last check.
activated_atstring (date-time)When the zone became active.

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
404not_found: the organization has no own name servers.
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/nameservers" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "ns": [
    "ns1.example-dns.net",
    "ns2.example-dns.net"
  ],
  "status": "pending",
  "detail": "",
  "required_ips": {
    "v4": [
      "example"
    ],
    "v6": [
      "example"
    ]
  },
  "ownership_txt": [
    {
      "name": "example.com",
      "value": "4f1c2e9a7b3d"
    }
  ],
  "checked_at": "2026-10-27T09:30:00Z",
  "activated_at": "2026-10-27T09:30:00Z"
}

Set own name servers

PUT /v1/orgs/{org}/whitelabel/nameservers

Sets two name servers of your own (for example ns1.example.com and ns2.example.com) to publish the organization's delegated zones instead of the assigned pair. They start pending. Before verifying them:

  1. Create the TXT records listed in ownership_txt.
  2. Make both names resolve exactly to the addresses in required_ips (A and AAAA; add glue records at the registrar when the names are inside your own domain).

Replacing active name servers makes the zones publish the assigned pair again until the new ones are verified.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Request body

Content type application/json.

FieldTypeRequiredDescription
nsarray of stringYesTwo different names, e.g. ns1.example.com and ns2.example.com. Exactly 2 items.

Response

FieldTypeDescription
nsarray of stringThe two own name servers.
statusstringOne of pending, active, error.
detailstringReason of the error status (empty if none).
required_ipsobjectAddresses both names must resolve to exactly (A and AAAA).
required_ips.v4array of string
required_ips.v6array of string
ownership_txtarray of objectTXT records proving that the organization controls the domain of its name servers; verification requires them before activation.
ownership_txt[].namestringName.
ownership_txt[].valuestring
checked_atstring (date-time)Last check.
activated_atstring (date-time)When the zone became active.

Errors

StatusDescription
400Malformed request (bad_request).
403The token's role or limits do not allow it (forbidden).
409host_taken: a name is used by another organization.
422Validation error (invalid).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X PUT "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/nameservers" \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "ns": [
      "ns1.acme.example",
      "ns2.acme.example"
    ]
  }'
200
{
  "ns": [
    "ns1.example-dns.net",
    "ns2.example-dns.net"
  ],
  "status": "pending",
  "detail": "",
  "required_ips": {
    "v4": [
      "example"
    ],
    "v6": [
      "example"
    ]
  },
  "ownership_txt": [
    {
      "name": "example.com",
      "value": "4f1c2e9a7b3d"
    }
  ],
  "checked_at": "2026-10-27T09:30:00Z",
  "activated_at": "2026-10-27T09:30:00Z"
}

Delete own name servers

DELETE /v1/orgs/{org}/whitelabel/nameservers

Removes the organization's own name servers; its delegated zones publish the assigned pair again.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

  • 204: Deleted. No body.

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
404Not found, or not visible to the token (not_found).
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/nameservers" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"

Verify own name servers

POST /v1/orgs/{org}/whitelabel/nameservers/verify

Checks the ownership TXT records and that both names resolve exactly to required_ips. When they do, the name servers become active and every delegated zone of the organization publishes them; otherwise the status is error and detail says what to fix.

Required role: admin or higher. Organization-wide.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).

Response

FieldTypeDescription
nsarray of stringThe two own name servers.
statusstringOne of pending, active, error.
detailstringReason of the error status (empty if none).
required_ipsobjectAddresses both names must resolve to exactly (A and AAAA).
required_ips.v4array of string
required_ips.v6array of string
ownership_txtarray of objectTXT records proving that the organization controls the domain of its name servers; verification requires them before activation.
ownership_txt[].namestringName.
ownership_txt[].valuestring
checked_atstring (date-time)Last check.
activated_atstring (date-time)When the zone became active.

Errors

StatusDescription
403The token's role or limits do not allow it (forbidden).
404Not found, or not visible to the token (not_found).
409host_taken: a name is used by another organization.
503Not available right now (unavailable); retry later.

Example

No SDK method yet: use the HTTP request.

curl -X POST "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/whitelabel/nameservers/verify" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "ns": [
    "ns1.example-dns.net",
    "ns2.example-dns.net"
  ],
  "status": "pending",
  "detail": "",
  "required_ips": {
    "v4": [
      "example"
    ],
    "v6": [
      "example"
    ]
  },
  "ownership_txt": [
    {
      "name": "example.com",
      "value": "4f1c2e9a7b3d"
    }
  ],
  "checked_at": "2026-10-27T09:30:00Z",
  "activated_at": "2026-10-27T09:30:00Z"
}

Last updated:

↑↓ to navigate↵ to openesc to close