Skip to main content
Use this flow when Peeker should buy the domains and run DNS. Your customer picks available domains; Peeker registers them, provisions the inboxes, and sends webhooks as work completes.

Steps in detail

1. Create your bundles

A bundle is a saved order size. Send name and monthly_sending_volume; optionally add google_percent and microsoft_percent. Bundles default to weekday-only sending (send_on_weekends: false) and 2 Google inboxes/domain. Use the returned bun_… ID on orders. The response also tells you how many Google and Microsoft domains the customer must pick.
cURL
curl -X POST "https://api.peeker.ai/partner/v1/bundles" \
  -H "Authorization: Bearer pk_test_<your-key>" \
  -H "Content-Type: application/json" \
  --data '
{
  "name": "Starter - 25k emails/month",
  "monthly_sending_volume": 25000,
  "send_on_weekends": false,
  "google_inboxes_per_domain": 2
}'
201 Created
{
	"data": {
		"id": "bun_01HZX0BU1A2B3C4D5E6F7G8H",
		"name": "Starter - 25k emails/month",
		"monthly_sending_volume": 25000,
		"google_percent": null,
		"microsoft_percent": null,
		"send_on_weekends": false,
		"google_inboxes_per_domain": 2,
		"effective": {
			"google_percent": 50,
			"microsoft_percent": 50
		},
		"required_domains": {
			"google": 15,
			"microsoft": 4,
			"total": 19
		},
		"status": "active",
		"created_at": "2026-05-08T12:00:00Z"
	}
}
Generate domain candidates yourself, or let the customer search. Send up to 50 per call. Available rows include price, renewal price, and usable_for; unavailable rows include a reason.
cURL
curl -X POST "https://api.peeker.ai/partner/v1/domains/availability" \
  -H "Authorization: Bearer pk_test_<your-key>" \
  -H "Content-Type: application/json" \
  --data '
{
  "domains": [
    "acme-mail.com",
    "team-acme.com",
    "premium-acme.com"
  ]
}'
200 OK
{
	"data": {
		"domains": [
			{
				"domain": "acme-mail.com",
				"available": true,
				"price_cents": 1300,
				"renewal_price_cents": 1500,
				"currency": "usd",
				"usable_for": ["google", "microsoft"]
			},
			{
				"domain": "team-acme.com",
				"available": true,
				"price_cents": 1300,
				"renewal_price_cents": 1500,
				"currency": "usd",
				"usable_for": ["google"]
			},
			{
				"domain": "premium-acme.com",
				"available": false,
				"premium": true,
				"reason": "premium"
			}
		]
	}
}
Microsoft domains must include "microsoft" in usable_for. Match the bundle’s required_domains.microsoft count before checkout. Filter or flag Google-only rows when the customer still needs Microsoft-capable domains.
POST /orders provisions everything in one call. It accepts one user string, plus Smartlead routing and credentials in sequencer. You pass:
  • bundle_id - the bundle from step 1; resolves the license mix and domain split.
  • user - an email to create/reuse, or an existing usr_… user ID.
  • sequencer - Smartlead routing plus the login credentials Peeker uses internally for provider submission.
  • forwarding_url - the default redirect for every domain in the order.
  • domains - the available domains you picked, selected to satisfy the bundle’s Microsoft split.
  • personas - names and required profile_picture_url keys used to generate inbox names.
Smartlead orders require both sequencer.login_email and sequencer.login_password; a Smartlead client ID or API key alone is not enough for Peeker to submit the provider work.Re-sending the exact same body returns the original order - no second charge, no duplicate provisioning. Orders dedupe for 24 hours.
cURL
curl -X POST "https://api.peeker.ai/partner/v1/orders" \
  -H "Authorization: Bearer pk_test_<your-key>" \
  -H "Content-Type: application/json" \
  --data '
{
  "user": "alex@acme.com",
  "bundle_id": "bun_01HZX0BU…",
  "sequencer": {
    "provider": "smartlead",
    "client_id": 366903,
    "login_email": "peeker@yourcompany.com",
    "login_password": "<your-dedicated-login>"
  },
  "forwarding_url": "https://acme.com",
  "domains": [
    "acme-mail.com",
    "team-acme.com"
  ],
  "personas": [
    {
      "first_name": "Alex",
      "last_name": "Rivera",
      "profile_picture_url": ""
    },
    {
      "first_name": "Sam",
      "last_name": "Lee",
      "profile_picture_url": ""
    }
  ]
}'
200 OK
{
	"data": {
		"id": "ord_01HZX0OR1A2B3C4D5E6F7G8H",
		"user_id": "usr_01HZX0C6Z3K4M5N6P7Q8R9S0",
		"email": "alex@acme.com",
		"bundle_id": "bun_01HZX0BU…",
		"status": "in_progress",
		"domain_count": 2,
		"costs": {
			"total_cents": 6800,
			"currency": "usd"
		},
		"created_at": "2026-05-08T12:00:00Z"
	}
}
If a domain cannot be registered at order time, the order rejects and you are not charged.
Configure your endpoint in the Partner portal → Webhooks before placing the order. Registrar-sourced domains skip the nameserver step (Peeker controls DNS), so events fire in this sequence:
order.in_progress  →  domain.connected (one per domain)  →  order.completed
The order.completed payload is the full order. Verify the signature before trusting any payload.
Webhook · order.completed
{
	"id": "evt_01HZX0EV2A2B3C4D5E6F7G8H",
	"type": "order.completed",
	"created_at": "2026-05-08T12:14:33Z",
	"data": {
		"id": "ord_01HZX0OR1A2B3C4D5E6F7G8H",
		"status": "completed",
		"domain_count": 2
	}
}

What’s next

Importing customer domains

The separate flow for domains the customer already owns at another registrar.

Change forwarding URLs

Repoint up to 25 domains at a new URL after the order is live.
Last modified on June 29, 2026