Hosted white-label
Configure a branded hosted experience, serve it from your own domain, provision customer access, and send customers into the correct project or location.
Configure white-label
Open the workspace in Signal, go to Settings → White label, and enable Hosted white label. Add the platform name, logo, favicon, bundled font, color palette, shape, text size, density, return destination, and return action text. Then choose which project and location navigation items customers can see.
return_url that uses an origin allowed by the issuing API key.Add a custom domain
Serve the hosted experience from your own hostname, such as ai.yourcompany.com, instead of Signal's address. Everything your customers load in the browser, including the login links you send them, stays on your domain, and Signal issues and renews the TLS certificate for you. Your backend keeps calling the public API at api.signal.ceyo.ai as before. Go to Settings → White label → Custom domain, enter the hostname, and create the CNAME record the card shows you.
# Create this record at your DNS provider. Use the exact target shown in Signal.
ai.yourcompany.com. CNAME domains.signal.ceyo.ai.
# Check propagation from your terminal.
dig +short CNAME ai.yourcompany.com
# domains.signal.ceyo.ai.yourcompany.com cannot carry a CNAME and are not supported. Do not add A or AAAA records for the hostname.Provision customer access
Use active project and location packages, stable external IDs, and a workspace API key. Create the resources, upsert an embedded identity, then grant that identity access to the required project or location. Viewer is read-only, editor manages supported operational features, and admin additionally manages general settings.
# Create the customer project and optional location.
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/projects' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{"name":"Acme","external_id":"customer-project","package_id":"{package_id}"}'
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/projects/customer-project/locations' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{"name":"Acme London","external_id":"customer-location","package_id":"{location_package_id}"}'
# Upsert the customer identity and grant project access.
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/embedded-identities/customer-user-42' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{"name":"Customer User"}'
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/embedded-identities/customer-user-42/projects/customer-project/access' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{"role":"viewer"}'Create hosted login links
Create links from your backend with a key that has login_links:manage. Each URL is short-lived, one-time, and scoped to the embedded identity's existing grant.
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/login-links' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"external_user_id": "customer-user-42",
"project_id": "customer-project",
"landing": "auto",
"return_url": "https://portal.partner.example/customers/42",
"expires_in": 900
}'landing with auto, projects, or locations. Use redirect_path instead when you need a specific internal page.GET /login-links/{login_link_id} or revoke a pending link with DELETE on the same path.