DomainDirectory
← Domain Directory

Developer & Embed Docs

Embed contact forms into any website, Next.js app, or Cloudflare Worker.

API v1

Available Form Types

Acquire the domain — collects bid price, phone, contact preference

Marketing / distribution partnerships — collects company info & partnership type

staffingpreview ↗

Join the team — collects team role, resume URL, developer flag

General inquiry — collects phone & contact preference

Option 1 — Direct URL (simplest)

Link directly to a hosted form page. No setup required. Works as a full page or in an iframe.

https://www.domaindirectory.com/forms/[type]/[domain]

Examples:

Add a button link in any HTML page:

html
<a href="https://www.domaindirectory.com/forms/offer/agentbank.com"
   target="_blank">
  Make an Offer
</a>

Option 2 — iframe Embed

Drop an iframe anywhere on your page. The form handles submission internally.

html
<iframe
  src="https://www.domaindirectory.com/forms/offer/agentbank.com"
  width="100%"
  height="700"
  style="border:none; border-radius:16px;"
  title="Make an offer for agentbank.com"
></iframe>

Tip: set height to 700–900px depending on form type. The partner and staffing forms are taller.

Option 3 — JS Widget (auto-render)

Load our script and place <div data-dd-form> elements anywhere on your page. The script bootstraps the form inside each matching element. Zero framework dependencies.

Step 1 — Load the script (once per page):

html
<script src="https://www.domaindirectory.com/widget/dd-forms.js" defer></script>

Step 2 — Place a container div:

html
<div
  data-dd-form="offer"
  data-dd-domain="agentbank.com"
></div>

All attributes:

AttributeRequiredValues
data-dd-formYesoffer | partner | staffing | inquire
data-dd-domainYese.g. agentbank.com

Option 4 — Next.js / React Component

If you're in a Next.js or React app, copy src/components/ServiceContactForm.tsx from the domaindirectory-nextjs repo and import it directly.

tsx
import { ServiceContactForm } from "@/components/ServiceContactForm";

// In your page / component:
<ServiceContactForm
  formType="offer"
  domain="agentbank.com"
  displayName="AgentBank.com"
/>

The component posts to https://www.domaindirectory.com/api/domain-contact by default. Your domain must be in the CORS allow-list — contact us to add it.

Option 5 — Cloudflare Worker Injection

Inject the widget script and container into any HTML response from a Cloudflare Worker.

javascript
// worker.js
export default {
  async fetch(request) {
    const response = await fetch(request);
    const html = await response.text();

    const snippet = `
<div data-dd-form="offer" data-dd-domain="agentbank.com"></div>
<script src="https://www.domaindirectory.com/widget/dd-forms.js" defer><\/script>
`;

    // Inject before </body>
    const modified = html.replace("</body>", snippet + "</body>");

    return new Response(modified, {
      headers: { "Content-Type": "text/html" },
    });
  },
};

API Reference

All forms POST to POST https://www.domaindirectory.com/api/domain-contact. CORS is enabled for registered portfolio domains.

FieldTypeRequiredNotes
domainstringYese.g. agentbank.com
emailstringYesValid email address
typestringNooffer | partner | staffing | inquire | contact
namestringNoSubmitter's name
phonestringNoPhone with country code
companystringNoCompany name
messagestringNoFree-text message
bid_pricenumberNoRequired when type=offer. Min $10,000

Example raw POST:

javascript
const res = await fetch("https://www.domaindirectory.com/api/domain-contact", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    domain: "agentbank.com",
    type: "offer",
    name: "Jane Smith",
    email: "[email protected]",
    bid_price: 50000,
    message: "I'm interested in acquiring this domain for a fintech startup.",
  }),
});

const data = await res.json();
// { success: true, message: "Thank you! Your message has been received." }
CORS & Allow-listing:Cross-origin API calls are allowed from pre-approved domains. If your domain isn't on the list, open a PR or contact the Domain Directory team to add it to ALLOWED_ORIGINS in src/app/api/domain-contact/route.ts.

Newsletter Subscription Widget

A lightweight email capture widget that posts to /api/leads. Collects name + email and saves a subscriber lead (tagged dd:newsletter). Drop it on any site — no framework required.

Live demo:

Subscribe to our newsletter

Get the latest updates straight to your inbox.

Step 1 — Load the script (once per page):

html
<script src="https://www.domaindirectory.com/widget/dd-newsletter.js" defer></script>

Step 2 — Place a container:

html
<div
  data-dd-newsletter
  data-dd-domain="agentbank.com"
></div>

Attributes (all optional):

AttributeDefaultNotes
data-dd-domaincurrent hostnameDomain the signup is tied to
data-dd-title"Subscribe to our newsletter"Heading text
data-dd-subtitle"Get the latest updates…"Subheading text
data-dd-button"Subscribe"Submit button label

Next.js / React component:

Copy src/components/NewsletterForm.tsx from the domaindirectory-nextjs repo and import it directly. It posts to /api/leads with source: "newsletter".

tsx
import { NewsletterForm } from "@/components/NewsletterForm";

// In your page / component:
<NewsletterForm
  domain="agentbank.com"
  title="Join the AgentBank list"
  subtitle="Product updates and early access."
  buttonLabel="Sign me up"
/>

Standalone React (no alias)? Point the fetch at the absolute URL https://www.domaindirectory.com/api/leads.

Cloudflare Worker injection:

Inject the newsletter widget into any HTML response from a Worker — great for parked / lander pages.

javascript
// worker.js
export default {
  async fetch(request) {
    const response = await fetch(request);
    const url = new URL(request.url);
    const host = url.hostname.replace(/^www\./, "");
    const html = await response.text();

    const snippet = `
<div data-dd-newsletter data-dd-domain="${host}"></div>
<script src="https://www.domaindirectory.com/widget/dd-newsletter.js" defer><\/script>
`;

    // Inject before </body>
    const modified = html.replace("</body>", snippet + "</body>");

    return new Response(modified, {
      headers: { "Content-Type": "text/html" },
    });
  },
};

The widget reads the current hostname automatically, so data-dd-domain is optional — set it explicitly if the signup should be tied to a different domain.

Customizing the look:

The widget ships neutral, generic styles driven by CSS variables — override any of them on the container (or a parent) to match your brand. No need to edit the script.

css
/* Theme the widget — set any of these on the container or :root */
[data-dd-newsletter] {
  --ddn-accent: #2563eb;        /* button + focus ring */
  --ddn-accent-hover: #1d4ed8;
  --ddn-radius: 8px;            /* corner roundness */
  --ddn-bg: #ffffff;           /* card background */
  --ddn-border: #e5e7eb;
  --ddn-text: #111827;
  --ddn-muted: #6b7280;
  --ddn-font: inherit;          /* use the host page's font */
  --ddn-shadow: none;
}

Every element has a stable class (.ddn-card, .ddn-input, .ddn-btn, …) for finer control, and you can attach your own hook class with data-dd-class. To start from a blank slate, drop the defaults entirely:

html
<!-- Option A: per-container, keep your own CSS only -->
<div data-dd-newsletter data-dd-unstyled data-dd-class="my-form"></div>

<!-- Option B: globally disable default CSS (before the script loads) -->
<script>window.DD_NEWSLETTER_NO_CSS = true;</script>
<script src="https://www.domaindirectory.com/widget/dd-newsletter.js" defer></script>

React component styling:

NewsletterForm accepts class overrides and an unstyled flag to strip all defaults.

tsx
<NewsletterForm
  domain="agentbank.com"
  className="rounded-none border-2 border-black bg-zinc-50 p-8"
  inputClassName="border-black"
  buttonClassName="bg-black hover:bg-zinc-800"
/>

// Or go fully custom — no default classes at all:
<NewsletterForm
  unstyled
  className="my-form"
  inputClassName="my-input"
  buttonClassName="my-button"
/>

Or POST directly:

javascript
const res = await fetch("https://www.domaindirectory.com/api/leads", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "[email protected]",
    name: "Jane Smith",
    domain_name: "agentbank.com",
    source: "newsletter",
  }),
});

const data = await res.json();
// { success: true } — or { success: true, message: "Already subscribed" }

CORS is open for this endpoint, so the newsletter widget works from any domain. Duplicate email + domain pairs are de-duplicated automatically.

Contact Us

Need your domain added to the CORS allow-list? Have a question about integration, embedding, or partnerships? Send us a message and we'll get back to you.