Kanorio

API 레퍼런스

Imports

Management API: GET /sites/{id}/imports, POST /sites/{id}/imports, GET /sites/{id}/imports/detect, …

이 페이지는 영어로만 제공됩니다. API 레퍼런스, Webhook 이벤트, 변경 내역은 코드의 필드 이름·오류 코드와 맞추기 위해 영어로 제공합니다.
Base URL https://app.kanorio.com/api/v1ErrorsPagination

List imports

GET/sites/{id}/imports
betaposts:viewdefault (120/minute per token)

List this website's recent import batches, newest first, all in one page (batches are kept for 7 days). Errors: FORBIDDEN.

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

Response 200

  • dataobject[]required
  • data[].idstringrequired
  • data[].operationIdstringrequired

    Pass to operations.get to poll; equals op_import_job_<id>.

  • data[].domain"POSTS" | "PRODUCTS" | "CONTACTS" | "COLLECTION_ITEMS"required
  • data[].inputKind"URL" | "FILE"required
  • data[].platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • data[].source"WP_REST" | "SQUARESPACE_JSON" | "BLOGGER_ATOM" | "GHOST_API" | "SITEMAP" | "RSS" | "LISTING" | "URL_LIST" | "WXR" | "BLOGGER_XML" | "FEED_FILE" | "MEDIUM_ZIP" | "SUBSTACK_ZIP" | "TUMBLR_ZIP" | "WEEBLY_ARCHIVE" | "GHOST_JSON" | "CSV_HTML" | "MARKDOWN" | "HTML" | "CONTACTS_CSV" | "VCARD" | "PRODUCTS_CSV" | "UNKNOWN"required
  • data[].status"PENDING" | "DISCOVERING" | "PARSING" | "REVIEW" | "APPLYING" | "POSTPROCESSING" | "DONE" | "FAILED" | "CANCELLED"required

    REVIEW means parsing is done and the batch waits for imports.apply: a human confirms the list (rows carry warnings such as duplicate_of, title_generated, empty_content).

  • data[].stagestring | nullrequired
  • data[].siteUrlstring | nullrequired
  • data[].fileNamestring | nullrequired
  • data[].totalsobjectrequired
  • data[].totals.discoveredintegerrequired
  • data[].totals.selectedintegerrequired
  • data[].totals.readyintegerrequired
  • data[].totals.duplicatesintegerrequired
  • data[].totals.importedintegerrequired
  • data[].totals.skippedintegerrequired
  • data[].totals.failedintegerrequired
  • data[].totals.discardedintegerrequired
  • data[].totals.linksRewrittenintegerrequired
  • data[].totals.pagesintegerrequired

    Pages found in the source that are not imported (only posts are).

  • data[].totals.attachmentsintegerrequired
  • data[].progressobject | nullrequired
  • data[].progress.currentintegerrequired
  • data[].progress.totalinteger | nullrequired
  • data[].errorCodestring | nullrequired
  • data[].createdAtstringrequired
  • data[].updatedAtstringrequired
  • data[].completedAtstring | nullrequired
  • data[].expiresAtstring | nullrequired

    Batch rows and the uploaded file are deleted after this time (7 days).

  • hasMorebooleanrequired

    True when another page exists; pass nextCursor to fetch it.

  • nextCursorstring | nullrequired

    Cursor for the next page, or null on the last page.

Errors

  • FORBIDDEN 403

MCP tool imports_list

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/imports" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "data": [
    {
      "id": "imp_example01",
      "operationId": "op_import_job_imp_example01",
      "domain": "POSTS",
      "inputKind": "URL",
      "platform": "WORDPRESS",
      "source": "WP_REST",
      "status": "DONE",
      "stage": null,
      "siteUrl": "https://old-blog.example.com",
      "fileName": null,
      "totals": {
        "discovered": 0,
        "selected": 0,
        "ready": 0,
        "duplicates": 0,
        "imported": 41,
        "skipped": 0,
        "failed": 0,
        "discarded": 0,
        "linksRewritten": 17,
        "pages": 6,
        "attachments": 120
      },
      "progress": {
        "current": 42,
        "total": 42
      },
      "errorCode": null,
      "createdAt": "2026-10-01T02:30:00.000Z",
      "updatedAt": "2026-10-06T08:00:00.000Z",
      "completedAt": "2026-10-06T08:00:00.000Z",
      "expiresAt": "2026-10-13T02:30:00.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}

Create an import

POST/sites/{id}/imports
betablog:managedefault (120/minute per token)Idempotency-Key

Start importing posts from an old site into this website as DRAFT posts. Give either siteUrl (the whole public post list is imported; large sites are discovered in the background and stop at REVIEW for confirmation) or urls (up to 20 specific post URLs). The batch runs in the background: poll with operations.get (operationId) or imports.get. After parsing it always stops at REVIEW: inspect rows with imports.get (failures, duplicates, generated titles, empty bodies) and call imports.apply to write the confirmed rows; nothing is written before that. Images are copied into the media library, categories/tags are reused or created, posts link to each other with the new paths, and the original publish date is kept. One active batch per site. Importing never consumes AI credits. Errors: FORBIDDEN, VALIDATION, IMPORT_IN_PROGRESS (details.batchId), IMPORT_DAILY_LIMIT_REACHED, SITE_UNREACHABLE, NO_LISTING.

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • Idempotency-Keystring · header

    Client-chosen key (1-200 chars). Retrying with the same key and the same body returns the original result; the same key with a different body is rejected with IDEMPOTENCY_CONFLICT (409). Keys expire after 24 hours.

Request body

  • siteUrlstring

    Public URL of the old site (homepage is enough), e.g. https://example.com.

  • urlsstring[]

    Specific post URLs instead of a whole site (max 20).

  • keepPublishedAtboolean

    Keep the original publish dates (default true).

Response 201

  • batchobjectrequired
  • batch.idstringrequired
  • batch.operationIdstringrequired

    Pass to operations.get to poll; equals op_import_job_<id>.

  • batch.domain"POSTS" | "PRODUCTS" | "CONTACTS" | "COLLECTION_ITEMS"required
  • batch.inputKind"URL" | "FILE"required
  • batch.platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • batch.source"WP_REST" | "SQUARESPACE_JSON" | "BLOGGER_ATOM" | "GHOST_API" | "SITEMAP" | "RSS" | "LISTING" | "URL_LIST" | "WXR" | "BLOGGER_XML" | "FEED_FILE" | "MEDIUM_ZIP" | "SUBSTACK_ZIP" | "TUMBLR_ZIP" | "WEEBLY_ARCHIVE" | "GHOST_JSON" | "CSV_HTML" | "MARKDOWN" | "HTML" | "CONTACTS_CSV" | "VCARD" | "PRODUCTS_CSV" | "UNKNOWN"required
  • batch.status"PENDING" | "DISCOVERING" | "PARSING" | "REVIEW" | "APPLYING" | "POSTPROCESSING" | "DONE" | "FAILED" | "CANCELLED"required

    REVIEW means parsing is done and the batch waits for imports.apply: a human confirms the list (rows carry warnings such as duplicate_of, title_generated, empty_content).

  • batch.stagestring | nullrequired
  • batch.siteUrlstring | nullrequired
  • batch.fileNamestring | nullrequired
  • batch.totalsobjectrequired
  • batch.totals.discoveredintegerrequired
  • batch.totals.selectedintegerrequired
  • batch.totals.readyintegerrequired
  • batch.totals.duplicatesintegerrequired
  • batch.totals.importedintegerrequired
  • batch.totals.skippedintegerrequired
  • batch.totals.failedintegerrequired
  • batch.totals.discardedintegerrequired
  • batch.totals.linksRewrittenintegerrequired
  • batch.totals.pagesintegerrequired

    Pages found in the source that are not imported (only posts are).

  • batch.totals.attachmentsintegerrequired
  • batch.progressobject | nullrequired
  • batch.progress.currentintegerrequired
  • batch.progress.totalinteger | nullrequired
  • batch.errorCodestring | nullrequired
  • batch.createdAtstringrequired
  • batch.updatedAtstringrequired
  • batch.completedAtstring | nullrequired
  • batch.expiresAtstring | nullrequired

    Batch rows and the uploaded file are deleted after this time (7 days).

Errors

  • FORBIDDEN 403
  • VALIDATION 400
  • IMPORT_IN_PROGRESS 409 · details.batchId
  • IMPORT_DAILY_LIMIT_REACHED 429
  • SITE_UNREACHABLE 422
  • NO_LISTING 422

MCP tool imports_create

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/imports" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"siteUrl":"https://old-blog.example.com","keepPublishedAt":true}'
Response
{
  "batch": {
    "id": "imp_example01",
    "operationId": "op_import_job_imp_example01",
    "domain": "POSTS",
    "inputKind": "URL",
    "platform": "WORDPRESS",
    "source": "WP_REST",
    "status": "PENDING",
    "stage": "parse",
    "siteUrl": "https://old-blog.example.com",
    "fileName": null,
    "totals": {
      "discovered": 0,
      "selected": 42,
      "ready": 0,
      "duplicates": 0,
      "imported": 0,
      "skipped": 0,
      "failed": 0,
      "discarded": 0,
      "linksRewritten": 0,
      "pages": 6,
      "attachments": 120
    },
    "progress": null,
    "errorCode": null,
    "createdAt": "2026-10-01T02:30:00.000Z",
    "updatedAt": "2026-10-06T08:00:00.000Z",
    "completedAt": null,
    "expiresAt": "2026-10-13T02:30:00.000Z"
  }
}

Detect imports

GET/sites/{id}/imports/detect
betaposts:viewdefault (120/minute per token)

Identify which platform an old website runs on (WordPress, Wix, Weebly, Squarespace, Blogger, Substack, Ghost, Medium…) by fetching its homepage once. Use it to tell the user what was found before calling imports.discover or imports.create. supportsUrlDiscovery=false (Medium) means posts can only be imported from an export file in the dashboard. Errors: FORBIDDEN, VALIDATION.

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • urlstring · queryrequired

    Public URL of the old site (homepage is enough), e.g. https://example.com.

Response 200

  • siteUrlstringrequired
  • platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • reachablebooleanrequired
  • supportsUrlDiscoverybooleanrequired

Errors

  • FORBIDDEN 403
  • VALIDATION 400

MCP tool imports_detect

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/imports/detect?url=https%3A%2F%2Fold-blog.example.com" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "siteUrl": "https://old-blog.example.com",
  "platform": "WORDPRESS",
  "reachable": true,
  "supportsUrlDiscovery": true
}

Discover imports

GET/sites/{id}/imports/discover
betaposts:viewdefault (120/minute per token)

List the posts an old site exposes publicly (WordPress REST, Squarespace JSON, Blogger Atom, sitemap, RSS or listing pages, chosen per platform). Nothing is written. Returns up to 2000 items; when the site is large or slow, mode=background is returned and imports.create should be called with the siteUrl so the worker discovers in the background. Errors: FORBIDDEN, VALIDATION, SITE_UNREACHABLE, NO_LISTING (no public post list; use an export file in the dashboard).

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • urlstring · queryrequired

    Public URL of the old site (homepage is enough), e.g. https://example.com.

Response 200

  • mode"list" | "background"required
  • platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • source"WP_REST" | "SQUARESPACE_JSON" | "BLOGGER_ATOM" | "GHOST_API" | "SITEMAP" | "RSS" | "LISTING" | "URL_LIST" | "WXR" | "BLOGGER_XML" | "FEED_FILE" | "MEDIUM_ZIP" | "SUBSTACK_ZIP" | "TUMBLR_ZIP" | "WEEBLY_ARCHIVE" | "GHOST_JSON" | "CSV_HTML" | "MARKDOWN" | "HTML" | "CONTACTS_CSV" | "VCARD" | "PRODUCTS_CSV" | "UNKNOWN" | nullrequired
  • itemsobject[]required
  • items[].sourceKeystringrequired
  • items[].urlstringrequired
  • items[].titlestring
  • items[].publishedAtstring
  • items[].kind"post" | "page" | "attachment" | "other"required
  • truncatedbooleanrequired
  • estimatedinteger | nullrequired

    When mode=background: how many posts were seen before stopping.

  • warningsstring[]required

Errors

  • FORBIDDEN 403
  • VALIDATION 400
  • SITE_UNREACHABLE 422
  • NO_LISTING 422 · no public post list; use an export file in the dashboard

MCP tool imports_discover

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/imports/discover?url=https%3A%2F%2Fold-blog.example.com" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "mode": "list",
  "platform": "WORDPRESS",
  "source": "WP_REST",
  "items": [
    {
      "sourceKey": "https://old-blog.example.com/2024/05/how-we-feed-our-starter",
      "url": "https://old-blog.example.com/2024/05/how-we-feed-our-starter",
      "title": "How we feed our sourdough starter",
      "publishedAt": "2024-05-01T12:00:00.000Z",
      "kind": "post"
    },
    {
      "sourceKey": "https://old-blog.example.com/2024/06/untitled-draft",
      "url": "https://old-blog.example.com/2024/06/untitled-draft",
      "kind": "post"
    }
  ],
  "truncated": false,
  "estimated": null,
  "warnings": []
}

Retrieve an import

GET/sites/{id}/imports/{batchId}
betaposts:viewdefault (120/minute per token)

Get one import batch with its rows (title, status, warnings, created post id and path). Row bodies are never returned. Filter rows with statuses (e.g. DUPLICATE,FAILED); rows is a page, pass limit and cursor (rows.nextCursor) to continue. Errors: FORBIDDEN, IMPORT_BATCH_NOT_FOUND, INVALID_CURSOR.

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • batchIdstring · pathrequired

    Import batch id. Get it from imports.create or imports.list.

  • statuses"DISCOVERED" | "SELECTED" | "READY" | "INCOMPLETE" | "DUPLICATE" | "IMPORTED" | "SKIPPED" | "FAILED" | "DISCARDED"[] · query
  • limitinteger · query

    Maximum number of items to return, 1–100. Defaults to 20.

  • cursorstring · query

    Opaque cursor from the previous page's nextCursor. Omit for the first page.

Response 200

  • batchobjectrequired
  • batch.idstringrequired
  • batch.operationIdstringrequired

    Pass to operations.get to poll; equals op_import_job_<id>.

  • batch.domain"POSTS" | "PRODUCTS" | "CONTACTS" | "COLLECTION_ITEMS"required
  • batch.inputKind"URL" | "FILE"required
  • batch.platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • batch.source"WP_REST" | "SQUARESPACE_JSON" | "BLOGGER_ATOM" | "GHOST_API" | "SITEMAP" | "RSS" | "LISTING" | "URL_LIST" | "WXR" | "BLOGGER_XML" | "FEED_FILE" | "MEDIUM_ZIP" | "SUBSTACK_ZIP" | "TUMBLR_ZIP" | "WEEBLY_ARCHIVE" | "GHOST_JSON" | "CSV_HTML" | "MARKDOWN" | "HTML" | "CONTACTS_CSV" | "VCARD" | "PRODUCTS_CSV" | "UNKNOWN"required
  • batch.status"PENDING" | "DISCOVERING" | "PARSING" | "REVIEW" | "APPLYING" | "POSTPROCESSING" | "DONE" | "FAILED" | "CANCELLED"required

    REVIEW means parsing is done and the batch waits for imports.apply: a human confirms the list (rows carry warnings such as duplicate_of, title_generated, empty_content).

  • batch.stagestring | nullrequired
  • batch.siteUrlstring | nullrequired
  • batch.fileNamestring | nullrequired
  • batch.totalsobjectrequired
  • batch.totals.discoveredintegerrequired
  • batch.totals.selectedintegerrequired
  • batch.totals.readyintegerrequired
  • batch.totals.duplicatesintegerrequired
  • batch.totals.importedintegerrequired
  • batch.totals.skippedintegerrequired
  • batch.totals.failedintegerrequired
  • batch.totals.discardedintegerrequired
  • batch.totals.linksRewrittenintegerrequired
  • batch.totals.pagesintegerrequired

    Pages found in the source that are not imported (only posts are).

  • batch.totals.attachmentsintegerrequired
  • batch.progressobject | nullrequired
  • batch.progress.currentintegerrequired
  • batch.progress.totalinteger | nullrequired
  • batch.errorCodestring | nullrequired
  • batch.createdAtstringrequired
  • batch.updatedAtstringrequired
  • batch.completedAtstring | nullrequired
  • batch.expiresAtstring | nullrequired

    Batch rows and the uploaded file are deleted after this time (7 days).

  • rowsobjectrequired
  • rows.dataobject[]required
  • rows.data[].idstringrequired
  • rows.data[].indexintegerrequired
  • rows.data[].sourceKeystringrequired

    Source identity: the normalized URL for URL imports, or a prefixed key such as wxr:<guid> for files.

  • rows.data[].titlestring | nullrequired
  • rows.data[].urlstring | nullrequired
  • rows.data[].status"DISCOVERED" | "SELECTED" | "READY" | "INCOMPLETE" | "DUPLICATE" | "IMPORTED" | "SKIPPED" | "FAILED" | "DISCARDED"required
  • rows.data[].warningsstring[]required
  • rows.data[].targetIdstring | nullrequired

    The created post id once IMPORTED.

  • rows.data[].targetPathstring | nullrequired

    Public path of the created post, e.g. /blog/my-post.

  • rows.data[].errorCodestring | nullrequired
  • rows.hasMorebooleanrequired

    True when another page exists; pass nextCursor to fetch it.

  • rows.nextCursorstring | nullrequired

    Cursor for the next page, or null on the last page.

Errors

  • FORBIDDEN 403
  • IMPORT_BATCH_NOT_FOUND 404
  • INVALID_CURSOR 400

MCP tool imports_get

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/imports/{batchId}" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "batch": {
    "id": "imp_example01",
    "operationId": "op_import_job_imp_example01",
    "domain": "POSTS",
    "inputKind": "URL",
    "platform": "WORDPRESS",
    "source": "WP_REST",
    "status": "DONE",
    "stage": null,
    "siteUrl": "https://old-blog.example.com",
    "fileName": null,
    "totals": {
      "discovered": 0,
      "selected": 0,
      "ready": 0,
      "duplicates": 0,
      "imported": 41,
      "skipped": 0,
      "failed": 0,
      "discarded": 0,
      "linksRewritten": 17,
      "pages": 6,
      "attachments": 120
    },
    "progress": {
      "current": 42,
      "total": 42
    },
    "errorCode": null,
    "createdAt": "2026-10-01T02:30:00.000Z",
    "updatedAt": "2026-10-06T08:00:00.000Z",
    "completedAt": "2026-10-06T08:00:00.000Z",
    "expiresAt": "2026-10-13T02:30:00.000Z"
  },
  "rows": {
    "data": [
      {
        "id": "row_example01",
        "index": 0,
        "sourceKey": "https://old-blog.example.com/2024/05/how-we-feed-our-starter",
        "title": "How we feed our sourdough starter",
        "url": "https://old-blog.example.com/2024/05/how-we-feed-our-starter",
        "status": "IMPORTED",
        "warnings": [],
        "targetId": "post_example01",
        "targetPath": "/blog/how-we-feed-our-starter",
        "errorCode": null
      },
      {
        "id": "row_example02",
        "index": 1,
        "sourceKey": "https://old-blog.example.com/2024/06/untitled-draft",
        "title": null,
        "url": "https://old-blog.example.com/2024/06/untitled-draft",
        "status": "READY",
        "warnings": [
          "title_generated",
          "no_published_date"
        ],
        "targetId": null,
        "targetPath": null,
        "errorCode": null
      }
    ],
    "hasMore": true,
    "nextCursor": "eyJvIjoyMCwicyI6IiJ9"
  }
}

Apply an import

POST/sites/{id}/imports/{batchId}/apply
betablog:managedefault (120/minute per token)

Confirm a batch that stopped at REVIEW: write the READY rows (and any DUPLICATE rows you explicitly pass in rowIds). Omit rowIds to import every READY row; rows you leave out are discarded. For background-discovered batches, rowIds selects which discovered posts to fetch and import. Rows with warnings (title_generated, empty_content) are written as-is; edit the drafts afterwards. Errors: FORBIDDEN, IMPORT_BATCH_NOT_FOUND, IMPORT_INVALID_STATE (batch is not in REVIEW).

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • batchIdstring · pathrequired

    Import batch id. Get it from imports.create or imports.list.

Request body

  • rowIdsstring[]

Response 200

  • batchobjectrequired
  • batch.idstringrequired
  • batch.operationIdstringrequired

    Pass to operations.get to poll; equals op_import_job_<id>.

  • batch.domain"POSTS" | "PRODUCTS" | "CONTACTS" | "COLLECTION_ITEMS"required
  • batch.inputKind"URL" | "FILE"required
  • batch.platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • batch.source"WP_REST" | "SQUARESPACE_JSON" | "BLOGGER_ATOM" | "GHOST_API" | "SITEMAP" | "RSS" | "LISTING" | "URL_LIST" | "WXR" | "BLOGGER_XML" | "FEED_FILE" | "MEDIUM_ZIP" | "SUBSTACK_ZIP" | "TUMBLR_ZIP" | "WEEBLY_ARCHIVE" | "GHOST_JSON" | "CSV_HTML" | "MARKDOWN" | "HTML" | "CONTACTS_CSV" | "VCARD" | "PRODUCTS_CSV" | "UNKNOWN"required
  • batch.status"PENDING" | "DISCOVERING" | "PARSING" | "REVIEW" | "APPLYING" | "POSTPROCESSING" | "DONE" | "FAILED" | "CANCELLED"required

    REVIEW means parsing is done and the batch waits for imports.apply: a human confirms the list (rows carry warnings such as duplicate_of, title_generated, empty_content).

  • batch.stagestring | nullrequired
  • batch.siteUrlstring | nullrequired
  • batch.fileNamestring | nullrequired
  • batch.totalsobjectrequired
  • batch.totals.discoveredintegerrequired
  • batch.totals.selectedintegerrequired
  • batch.totals.readyintegerrequired
  • batch.totals.duplicatesintegerrequired
  • batch.totals.importedintegerrequired
  • batch.totals.skippedintegerrequired
  • batch.totals.failedintegerrequired
  • batch.totals.discardedintegerrequired
  • batch.totals.linksRewrittenintegerrequired
  • batch.totals.pagesintegerrequired

    Pages found in the source that are not imported (only posts are).

  • batch.totals.attachmentsintegerrequired
  • batch.progressobject | nullrequired
  • batch.progress.currentintegerrequired
  • batch.progress.totalinteger | nullrequired
  • batch.errorCodestring | nullrequired
  • batch.createdAtstringrequired
  • batch.updatedAtstringrequired
  • batch.completedAtstring | nullrequired
  • batch.expiresAtstring | nullrequired

    Batch rows and the uploaded file are deleted after this time (7 days).

Errors

  • FORBIDDEN 403
  • IMPORT_BATCH_NOT_FOUND 404
  • IMPORT_INVALID_STATE 409 · batch is not in REVIEW

MCP tool imports_apply

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/imports/{batchId}/apply" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rowIds":["row_example01"]}'
Response
{
  "batch": {
    "id": "imp_example01",
    "operationId": "op_import_job_imp_example01",
    "domain": "POSTS",
    "inputKind": "URL",
    "platform": "WORDPRESS",
    "source": "WP_REST",
    "status": "PENDING",
    "stage": "apply",
    "siteUrl": "https://old-blog.example.com",
    "fileName": null,
    "totals": {
      "discovered": 0,
      "selected": 0,
      "ready": 0,
      "duplicates": 0,
      "imported": 41,
      "skipped": 0,
      "failed": 0,
      "discarded": 0,
      "linksRewritten": 17,
      "pages": 6,
      "attachments": 120
    },
    "progress": {
      "current": 42,
      "total": 42
    },
    "errorCode": null,
    "createdAt": "2026-10-01T02:30:00.000Z",
    "updatedAt": "2026-10-06T08:00:00.000Z",
    "completedAt": null,
    "expiresAt": "2026-10-13T02:30:00.000Z"
  }
}

Cancel an import

POST/sites/{id}/imports/{batchId}/cancel
betablog:managedefault (120/minute per token)

Cancel an active import batch between rows. Posts already written stay as drafts; delete them from the posts list if unwanted. Errors: FORBIDDEN, IMPORT_BATCH_NOT_FOUND, IMPORT_INVALID_STATE.

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • batchIdstring · pathrequired

    Import batch id. Get it from imports.create or imports.list.

Response 200

  • batchobjectrequired
  • batch.idstringrequired
  • batch.operationIdstringrequired

    Pass to operations.get to poll; equals op_import_job_<id>.

  • batch.domain"POSTS" | "PRODUCTS" | "CONTACTS" | "COLLECTION_ITEMS"required
  • batch.inputKind"URL" | "FILE"required
  • batch.platform"WORDPRESS" | "WIX" | "WEEBLY" | "SQUARESPACE" | "BLOGGER" | "SUBSTACK" | "GHOST" | "MEDIUM" | "TUMBLR" | "WEBFLOW" | "HUBSPOT" | "SHOPIFY" | "WOOCOMMERCE" | "MAILCHIMP" | "KLAVIYO" | "GOOGLE_CONTACTS" | "OUTLOOK" | "GENERIC" | "UNKNOWN"required
  • batch.source"WP_REST" | "SQUARESPACE_JSON" | "BLOGGER_ATOM" | "GHOST_API" | "SITEMAP" | "RSS" | "LISTING" | "URL_LIST" | "WXR" | "BLOGGER_XML" | "FEED_FILE" | "MEDIUM_ZIP" | "SUBSTACK_ZIP" | "TUMBLR_ZIP" | "WEEBLY_ARCHIVE" | "GHOST_JSON" | "CSV_HTML" | "MARKDOWN" | "HTML" | "CONTACTS_CSV" | "VCARD" | "PRODUCTS_CSV" | "UNKNOWN"required
  • batch.status"PENDING" | "DISCOVERING" | "PARSING" | "REVIEW" | "APPLYING" | "POSTPROCESSING" | "DONE" | "FAILED" | "CANCELLED"required

    REVIEW means parsing is done and the batch waits for imports.apply: a human confirms the list (rows carry warnings such as duplicate_of, title_generated, empty_content).

  • batch.stagestring | nullrequired
  • batch.siteUrlstring | nullrequired
  • batch.fileNamestring | nullrequired
  • batch.totalsobjectrequired
  • batch.totals.discoveredintegerrequired
  • batch.totals.selectedintegerrequired
  • batch.totals.readyintegerrequired
  • batch.totals.duplicatesintegerrequired
  • batch.totals.importedintegerrequired
  • batch.totals.skippedintegerrequired
  • batch.totals.failedintegerrequired
  • batch.totals.discardedintegerrequired
  • batch.totals.linksRewrittenintegerrequired
  • batch.totals.pagesintegerrequired

    Pages found in the source that are not imported (only posts are).

  • batch.totals.attachmentsintegerrequired
  • batch.progressobject | nullrequired
  • batch.progress.currentintegerrequired
  • batch.progress.totalinteger | nullrequired
  • batch.errorCodestring | nullrequired
  • batch.createdAtstringrequired
  • batch.updatedAtstringrequired
  • batch.completedAtstring | nullrequired
  • batch.expiresAtstring | nullrequired

    Batch rows and the uploaded file are deleted after this time (7 days).

Errors

  • FORBIDDEN 403
  • IMPORT_BATCH_NOT_FOUND 404
  • IMPORT_INVALID_STATE 409

MCP tool imports_cancel

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/imports/{batchId}/cancel" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
Response
{
  "batch": {
    "id": "imp_example01",
    "operationId": "op_import_job_imp_example01",
    "domain": "POSTS",
    "inputKind": "URL",
    "platform": "WORDPRESS",
    "source": "WP_REST",
    "status": "CANCELLED",
    "stage": null,
    "siteUrl": "https://old-blog.example.com",
    "fileName": null,
    "totals": {
      "discovered": 0,
      "selected": 0,
      "ready": 0,
      "duplicates": 0,
      "imported": 41,
      "skipped": 0,
      "failed": 0,
      "discarded": 0,
      "linksRewritten": 17,
      "pages": 6,
      "attachments": 120
    },
    "progress": {
      "current": 42,
      "total": 42
    },
    "errorCode": null,
    "createdAt": "2026-10-01T02:30:00.000Z",
    "updatedAt": "2026-10-06T08:00:00.000Z",
    "completedAt": null,
    "expiresAt": "2026-10-13T02:30:00.000Z"
  }
}