KoalaWriter API

The KoalaWriter API is the best API for creating SEO-optimized articles. It is billed based on the number of words generated, the same as if you were using KoalaWriter manually. All paid plans can use this API with no additional costs.

How It Works

The KoalaWriter API is asynchronous, meaning the article is created in the background. The process works as follows:

  1. Make an API call to queue an article for writing
  2. Call the API to check the status of the article
  3. Once the status is finished, access the full HTML of the completed article

When an article is completed, it is automatically saved to your account so you can also access it there.

You can specify an integrationId so that when the article is completed it will automatically be created as a draft in WordPress, Shopify, Webflow, etc! Webhooks are also supported by specifying the webhookUrl parameter.

If you are just wanting to do bulk writing, please check out the Bulk Mode in KoalaWriter.

Endpoints

Creating an Article

POST https://koala.sh/api/articles/

Example Request

fetch("https://koala.sh/api/articles/", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    targetKeyword: "can you eat watermelon seeds?",
    gptVersion: "gpt-4o",
    integrationId: "329cf56d-5409-43f3-b7fc-9cb64d725f6c",
  }),
});

Example Response

{"articleId": "7b53671d-da26-4ab1-b096-6e014125f712"}

Parameters

Below is a full list of available parameters. Only the targetKeyword is required.

NameType / Possible ValuesDescription
targetKeywordstringThe main keyword for the article.
integrationIdstringProvide an integration ID for a connected site and we will automatically create a draft.
webhookUrlstringYou can provide a URL and we will POST to it when the article is completed. The payload will contain the same response as the /api/articles/{article_id} route.
gptVersion"gpt-4o-mini" (default), "gpt-4o", or "claude-3.7-sonnet"The model to be used.
articleType"blog_post" (default), "amazon_product_roundup", "youtube_video", "rewrite_blog_post", "amazon_single_product_review", "listicle", "local_places_roundup"The type of article to be generated.
autoPolishboolean, defaults to falseIf enabled, we will automatically run Polish on the article using the settings below.
polishSettingsobject, defaults to {"split-up-long-paragraphs":true,"remove-mid-article-conclusions":true,"remove-repetitive-sentences":true,"convert-passive-voice":false,"simplify-complex-sentences":false}The Polish settings to be used. autoPolish must be set to true for this to take effect.
language"English" (default) or any available language supported by KoalaWriterThe language to be used.
pointOfView"third_person" (default), "first_person_singular", "first_person_plural", "second_person"The point of view to be used in the article.
extraTitlePromptstringAn additional prompt to be used for generating the article title.
extraSectionPromptstringAn additional prompt to be used for each section.
extraIntroductionPromptstringAn additional prompt to be used for the introduction.
toneOfVoiceProfile"seo_optimized" (default) or any string (e.g. "Friendly")The tone of voice to be used for the article.
titlestringYou can provide a title if you don't want us to generate one for you.
includeFaqboolean, defaults to falseIf enabled, we will add a FAQ section based on real-time data.
readabilityMode"default" or "8th_grade"If set to "8th_grade", the output will contain shorter sentences and simpler language to target an 8th grade reading level.
The below parameters only apply to the "blog_post" article type. This is the default article type.
realTimeDataboolean, defaults to falseWhether to use real-time data for the article.
shouldCiteSourcesboolean, defaults to trueWhether to include links to sources used in the article.
seoOptimizationLevel "default" (default), "manual", "ai_powered"The SEO optimization mode to apply to the article.
extraEntitiesPromptstringA comma-separated list of keywords/entities to cover in the article. Only used if seoOptimizationLevel is manual.
includeKeyTakeawaysboolean, defaults to falseIf enabled, a new version of the introduction will be used that includes a Key Takeaways section.
outlinearray of SectionsPlease read the documentation and contact us if you require more information. By default, we will generate an outline for you based on the target keyword.
extraOutlinePromptstringEach section (H2) should be on a new line and you can specify sub-sections (H3s) by indenting them. Only one level of indentation is supported. You should only include the names of the sections. Use the outline parameter instead if you want full control over the outline.
countrystringThe country to be targeted in the article.
urlsarray of stringsArray of URLs to be used as references in the article.
disableIntroductionbooleanWhether to disable the introduction of the article.
disableConclusionbooleanWhether to disable the conclusion of the article.
multimediaOption"none" (default), "auto", "images", "videos"The type of multimedia to include in the article.
imageStyle"illustration" (default), "photo", "watercolor", "fantasy", "anime", "isometric"Style of the images to be included.
imageModel"standard" (default), "premium"Model to be used for generating AI images.
maxImagesintegerMaximum number of images to include.
imageSizestringSize of the images to be included (must be a supported size here).
maxVideosintegerMaximum number of videos to include.
articleLength"default" (default), "custom", "short", "shorter", "medium", "long", "longer"Please refer to KoalaWriter to see the range of sections and estimated word count for each option. Set to "custom" if you want to manually specify the number of sections in the numberOfSections field.
numberOfSectionsintegerThe number of sections to include. You must set articleLength to "custom" if you want this to take effect.
The below parameters only apply to the "listicle" and "local_places_roundup" article types.
enableSupplementalInformationboolean, defaults to trueBy default, 1-3 relevant sections will be added at the end of article. This is recommended for a comprehensive and optimized article. Set to false to disable.
enableAutomaticLengthboolean, defaults to trueBy default, if a number of items is specified in the Target Keyword then that will be used, otherwise it will default to 10. For example, "5 cutest dog breeds" would use 5 items. Override this by setting this to false and specifying the number of items in the numberOfItems parameter.
numberOfItemsinteger, default 10You must set enableAutomaticLength to false if you want this to take effect. This is the number of items to include in the listicle.
The below parameters only apply to the "amazon_product_roundup" article type.
amazonDomain"amazon.com" (default) or any Amazon domain supported by KoalaWriterThe domain of the Amazon store to search for products in.
numAmazonProductsinteger from 1 to 48, defaults to 10The number of Amazon products to include in the article.
enableFirstHandExperienceboolean, defaults to trueWhether to include the first-hand experience with the Amazon products.
amazonAssociatesId stringThe Amazon Associates ID to use for affiliate linking.
amazonProductSearchUrl stringThe URL of the Amazon product search to use.
Parameters for "youtube_video" article type:
youTubeVideoUrlstringURL of the YouTube video to be processed.
rewriteAllSourceDatabooleanWhether to rewrite all source data of the video.
Parameters for "rewrite_blog_post" article type:
articleUrlstringURL of the article to be rewritten.
rewriteAllSourceDatabooleanWhether to rewrite all source data of the article.
Parameters for "amazon_single_product_review" article type:
asinstringAmazon Standard Identification Number for the product.
enableCondensedModebooleanWhether to enable condensed mode for the product review.

Checking Article Status

GET https://koala.sh/api/articles/{article_id}

This endpoint is used to check the status of an article and to get the HTML (if it is finished).

Example Response (Completed Article)

{
  "config": {
    "targetKeyword": "are great danes good pets?"
  },
  "status": "finished",
  "statusDetail": "Finished article",
  "updatedAt": 1683095362612,
  "progress": 1,
  "error": null,
  "output": {
    "html": "<h1>Are Great Danes Good Pets? Pros and Cons You Need to Know</h1><h2>Introduction</h2><p>Great Danes are one of the largest dog breeds in the world, known for their majestic appearance and gentle nature...",
    "polishedHtml": null
  }
}

polishedHtml will be null unless autoPolish was set to true or the article was manually polished in KoalaWriter.

Example Response (In Progress)

{
  "config": {
    "targetKeyword": "are great danes good pets?"
  },
  "status": "processing",
  "statusDetail": "Writing section 3",
  "updatedAt": 1683095271489,
  "progress": 0.33,
  "error": null
}

Status Values

  • queued: The article is queued
  • processing: The article is being written
  • finished: The article is finished 🎉
  • failed: An error occurred and we could not finish writing the article

Complete Example

async function createAndWaitForArticle(keyword) {
  try {
    // Step 1: Create the article
    const createResponse = await fetch("https://koala.sh/api/articles/", {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        targetKeyword: keyword,
        gptVersion: "gpt-4o",
      }),
    });

    if (!createResponse.ok) {
      throw new Error(`Failed to create article: ${createResponse.status}`);
    }

    const { articleId } = await createResponse.json();
    console.log(`Article created with ID: ${articleId}`);

    // Step 2: Poll for article status
    let articleFinished = false;
    let article = null;

    while (!articleFinished) {
      const statusResponse = await fetch(
        `https://koala.sh/api/articles/${articleId}`,
        {
          headers: {
            Authorization: "Bearer YOUR_API_KEY",
          },
        }
      );

      if (!statusResponse.ok) {
        throw new Error(`Failed to check article status: ${statusResponse.status}`);
      }

      article = await statusResponse.json();
      
      if (article.status === "finished") {
        articleFinished = true;
        console.log("Article is complete!");
      } else if (article.status === "failed") {
        throw new Error(`Article failed: ${article.error}`);
      } else {
        console.log(`Article status: ${article.status} - ${article.statusDetail || "In progress"} (${Math.round(article.progress * 100)}%)`);
        // Wait 5 seconds before checking again
        await new Promise(resolve => setTimeout(resolve, 5000));
      }
    }

    // Step 3: Use the completed article
    console.log("Article HTML:", article.output.html);
    return article;
  } catch (error) {
    console.error("Error:", error);
    return null;
  }
}

// Example usage
createAndWaitForArticle("best hiking trails in colorado");

Error Handling

The API will return appropriate HTTP status codes for different error conditions:

  • 400 Bad Request: Invalid parameters or request format
  • 401 Unauthorized: Invalid or missing API key
  • 500 Internal Server Error: Server-side error

Need Help?

If you need additional assistance with the KoalaWriter API, please contact us.