docs

Ingest domains

Coming soon. Send telemetry to a subdomain you own, such as errors.crafty.gg, instead of the default Unhandled host.

By default your SDKs send telemetry to the Unhandled ingest host. An ingest domain lets an organization use a subdomain it owns instead. Requests from your app then go to your own zone, which keeps ad blockers away from browser telemetry, lets a strict CSP name only your domains, and keeps a vendor name out of your DSNs.

It is optional. The default host keeps accepting every key, so nothing changes until you deploy a DSN with the new host.

Example: errors.crafty.gg

Crafty runs crafty.gg and wants its errors, traces and logs to go to errors.crafty.gg.

  1. Add the domain

    An organization admin opens Settings → Ingest domain, enters errors.crafty.gg and clicks Add domain. Each organization has at most one ingest domain.

  2. Create two DNS records

    The page lists the exact records. At Crafty's DNS provider:

    TypeNameValue
    TXT_unhandled-verify.errors.crafty.ggunhandled-verify=<token from the page>
    CNAMEerrors.crafty.ggcname.ingest.unhandled.net

    The TXT record proves Crafty owns the name. The CNAME routes traffic to Unhandled.

  3. Check DNS

    Click Check DNS, or wait: Unhandled checks every minute for the first 15 minutes, then every 15 minutes. A domain whose TXT record is still missing after 7 days is removed, and you add it again to get a new token. The status moves from Waiting for DNS to Provisioning SSL to Active once the certificate is issued.

  4. Deploy the new DSN

    When the domain is active, every new DSN uses it:

    https://uh_live_…@errors.crafty.gg/7c9e6679-7425-40de-944b-e07fc1f90ae7

    Rotate the key of a service, or replace the host in the DSN you already deploy, then redeploy. The Connect dialog, the setup snippets, the AI prompt and the MCP setup_service tool all show https://errors.crafty.gg as the endpoint.

What the domain serves

An ingest domain carries telemetry and nothing else.

PathPurpose
POST /v1/traces, /v1/logs, /v1/metricsOpenTelemetry over HTTP, from the Unhandled agents and any OTLP SDK
OPTIONS on the same pathsCORS preflight for the browser SDK
POST /api/<project id>/envelope/, /api/<project id>/store/Sentry SDKs
POST /api/v1/sourcemapsSource map uploads from the CLI, which takes the host from the DSN

The ingest receiver answers the OpenTelemetry and Sentry paths, and the web app answers the source map upload. Every other path answers 404. The dashboard, login and OAuth are never reachable on it, and it never sets a cookie.

Which keys it accepts

The domain belongs to your organization, so it accepts your organization's keys only. A key from another organization gets 403 API key does not belong to this ingest domain. This stops anyone from shipping a DSN that depends on a hostname they do not control.

Your keys keep working on the default host as well, so you can move services one at a time.

Browser SDK and CORS

The browser SDK sends its key in custom headers, so browsers send a CORS preflight first. The ingest domain answers it like the default host does, and each service's allowed websites still apply. With a strict Content Security Policy, allow the ingest domain:

Content-Security-Policy: connect-src 'self' https://errors.crafty.gg

Remove the domain

Remove on the settings page turns the domain off. New DSNs go back to the default host at once. SDKs still sending to errors.crafty.gg fail once its certificate is gone, so deploy DSNs with the default host first.