---
title: "Resolve a domain to its owning org and any matching products"
method: GET
path: "/lookups/by-domain"
tags: ["Lookups"]
---

# Resolve a domain to its owning org and any matching products

`GET /lookups/by-domain`

Normalizes the input domain (lowercased, no scheme/path/www), exact-matches against `organizations.domain` (primary) and `domain_aliases.domain` (alias for either an org or a product), and returns whatever it finds.

On a complete miss, when `listing-self-serve-enabled` is on, the handler may probe `https://{domain}/.well-known/releases.json` in-request and materialize a stub org (basis: declared) via the same core as the listing activate path and the domain-demand cron. Probe budget is per-domain (a few attempts per ~10 min rolling window) plus a per-IP rate limit on the outbound branch; budget exhaustion returns 404 (not 429). Misses still record `domain_demand` for the nightly sweep backstop.

Products can be populated even when `org` is null — a product alias may point at a domain its parent org doesn't claim as primary.

## Query parameters

- `domain` string, required

## Response `200`

Resolved org and/or product matches (including a just-materialized stub)

- object
  - `domain` string, required
  - `org` object, nullable, required
    - `id` string, required
    - `slug` string, required
    - `name` string, required
    - `domain` string, nullable, required
    - `description` string, nullable, required
    - `category` string, nullable, required
    - `avatarUrl` string, nullable, required
    - `matchedVia` 'primary' | 'alias', required
    - `status` 'stub' | 'tracked'
    - `locations` object[]
      - `url` string
      - `feed` string
      - `github` string
      - `appstore` string
      - `file` string
      - `title` string, nullable
      - `canonical` boolean, required
      - `basis` 'curator' | 'declared' | 'detected' | 'generated', required
      - `productId` string, nullable, required
      - `sourceId` string, nullable, required
  - `products` object[], required
    - `id` string, required
    - `slug` string, required
    - `name` string, required
    - `orgId` string, required
    - `orgSlug` string, required
    - `orgName` string, required
    - `category` 'ai' | 'cloud' | 'commerce' | 'crm' | 'database' | 'design' | 'developer-tools' | 'devops' | 'finance' | 'framework' | 'infrastructure' | 'observability' | 'productivity' | 'security', nullable, required
    - `kind` 'platform' | 'sdk' | 'mobile' | 'desktop' | 'docs' | 'integration' | 'tool', nullable

## Other responses

- `400` — Missing or invalid `domain` query parameter
- `404` — Domain doesn't match any registered org or product (and JIT found no valid manifest)
- `429` — Per-IP rate limit on the outbound JIT probe branch

---

[API](https://skmtc.net/releases/apis/releases-api.md) · [All operations](https://skmtc.net/releases/apis/releases-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/releases/releases-api/versions/168e32061f53/schema)
