Import

Import a website from its URL into a draft

Starts an import job that copies a website into a draft site at {slug}, creating the site. When you already own {slug} the import is refused (409 slug_taken_self) unless you send onSlugTaken: merge, which adds or updates the pages on that site. The call answers 202 straight away. Poll GET /api/v1/sites/{slug}/jobs/{id} with job.id until status is succeeded or failed, or watch GET /api/v1/sites/{slug}/import-status. Use the slug in the response from then on: it can differ from the one you sent.

Send only sourceUrl to import the whole site: Dotsy finds the pages from the sitemap and the home page links. Everything lands in the draft and nothing is live until you publish. Guest tokens cannot import; use an account key.

post/api/v1/sites/{slug}/import/url

Request

  • Base URL: https://api.dotsy.ai
  • URL: https://api.dotsy.ai/api/v1/sites/{slug}/import/url
  • Auth: HTTP bearer

Path parameters

slugstring required
Example:acme-studio

Site slug or site id (UUID). An old slug answers 301/308 and a site id 307 to the canonical slug path.

Headers

X-Dotsy-Workspacestring

Org id or slug to act as for this request (session/MCP user actors only — ignored for pga_ keys). Validated against the caller's own memberships (id match first, then slug); 403 if not a member. Takes precedence over session.activeOrganizationId and the auto-provisioned home-workspace fallback.

Request body

sourceUrlstring uri required

The website to import. Without pages and segments, Dotsy imports the whole site it can discover from here.

mode'auto' | 'mirror' | 'render'

Default auto.

keyConvention'flat' | 'directory'

Shape of the content keys. directory stores about/index.html (static-site output); flat (default) stores about.html.

onSlugTaken'auto-suffix' | 'fail' | 'merge'

What to do when {slug} is already in use. auto-suffix (default): when another account holds it, import into {slug}-{adjective}-{noun} instead; when you own it, answer 409 slug_taken_self. fail: when another account holds it, answer 409 slug_taken with suggestions. merge: when you own it, add or update the pages on that site; when another account holds it, behaves like auto-suffix.

assetMirror'full' | 'same-host' | 'off'

Which asset URLs are copied into Dotsy. full (default): the source's own assets and the cross-origin assets they use (CDN images, fonts, scripts). same-host: only assets served from the source host. off: none, so asset URLs keep pointing at the source.

assetWarm'auto' | 'inline' | 'deferred'

When mirrored assets are copied. inline: during the import. deferred: in a background job afterwards. auto (default): inline up to 100 external assets, deferred beyond.

skipHostsstring[]

Asset hosts to leave alone: matching URLs stay pointing at the source.

mirrorHostsstring[]

With assetMirror: full, copy cross-origin assets only from hosts that match one of these.

Example request

{
  "sourceUrl": "https://example.com",
  "pages": [
    {
      "url": "/about",
      "key": "about.html"
    }
  ],
  "segments": [
    {
      "pathPrefix": "/blog"
    }
  ],
  "skipHosts": [
    "cdn.example-analytics.com"
  ]
}

Response

The import is queued.

idstring required

The import's workflow id. Poll the job with job.id on GET /api/v1/sites/{slug}/jobs/{id}. The legacy URL GET …/import/url/{id} still answers for this id.

status'queued' required
slugstring required

The slug the site is imported into. It differs from the {slug} you sent when slugAdjusted is true.

requestedSlugstring required
slugAdjustedboolean required

True when another account held the slug and a suffix was added.

pagesinteger required

Pages queued for capture.

warningsstring[] required

Notes from page discovery: capped sitemaps (import_discovery_capped), key collisions, routes the import would shadow.

remainingByPrefixobject

Pages left out by a cap, by path prefix. Present only when a cap cut the discovery short.

assetsHintstring

Where to find the copy progress of mirrored assets. Present when assetMirror is full.

publicUrlstring required
liveUrlstring required
liveReadyfalse required

Always false: an import lands in the draft until you publish.

Example response

{
  "publicUrl": "https://acme-studio.dotsy.site/"
}

Changes

No recorded changes to this operation across all 1 revision of this API.