# Instagram Caption Checker: Fix Captions for the 5-Hashtag Limit (`feedwise/instagram-caption-checker`) Actor

Bulk-check Instagram captions against the new 5-hashtag limit and 2,200-character cap. Get each caption fixed: the 5 most relevant hashtags kept, spam and generic tags removed, plus hook, link and call-to-action tips. For agencies, schedulers and caption libraries.

- **URL**: https://apify.com/feedwise/instagram-caption-checker.md
- **Developed by:** [Feedwise Data](https://apify.com/feedwise) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 caption checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Caption Checker — fix captions for the 5-hashtag limit

Since **December 2025 Instagram allows only 5 hashtags per post and Reel** (caption and first comment
combined). Posts with more are blocked or lose their extra tags, and most caption templates, saved
libraries and scheduled posts still carry 15–30 tags.

Paste your captions (one or thousands) and get, for each one:

- **Rule check**: hashtags over the limit, captions over 2,200 characters, more than 20 @mentions.
- **A fixed caption**, ready to paste: your text untouched, the **5 most relevant hashtags kept**,
  engagement-bait tags (#like4like, #follow4follow…) and very broad tags (#love, #instagood…)
  removed, spacer dots cleaned up. Tags inside sentences keep their word ("I love #coffee" stays
  readable as "I love coffee" if the tag is dropped).
- **Suggested hashtags**: the 5 to keep, ranked by how well they match what the caption is about,
  topped up with keyword ideas from the caption when you have fewer than 5.
- **Hook check**: the ~125 characters shown before "more", and a warning if they're wasted on
  hashtags or mentions.
- **Tips**: links that won't be clickable, missing call to action, duplicate and overlong tags.
- **Brand hashtags** you list are always kept.

No Instagram login, no account access: it works on the text you give it, so it's instant and safe.

### Who it's for

- **Social media agencies** migrating caption libraries and client templates to the 5-tag rule.
- **Schedulers and SaaS tools** that need a bulk pre-publish check (call it from the API).
- **Creators and brands** cleaning up drafts and evergreen posts.

### Input

```json
{
  "posts": [
    {
      "id": "cold-brew-launch",
      "caption": "Our new oat milk cold brew is here! ... #coffee #coldbrew #oatmilk #love #like4like ...",
      "firstComment": "#coffeetime #latteart"
    }
  ],
  "brandHashtags": ["#austinbeans"],
  "maxHashtags": 5
}
```

### Output (one row per caption)

```json
{
  "id": "cold-brew-launch",
  "ok": false,
  "issues": ["17 hashtags: Instagram allows 5 per post (caption and first comment combined); extra tags are blocked or dropped", "Engagement-bait hashtags can limit reach: #like4like #follow4follow"],
  "tips": ["Very broad hashtags rarely help discovery: #love #instagood #photooftheday"],
  "hashtagCount": 17,
  "suggestedHashtags": ["#coldbrew", "#oatmilk", "#austincoffee", "#smallbatch", "#austintx"],
  "characters": 343,
  "previewText": "Sunday reset ☕ Our new oat milk cold brew is finally here! ...",
  "fixedCaption": "Sunday reset ☕ Our new oat milk cold brew is finally here! ...\nWhich flavor should we drop next? Comment below 👇\n#coldbrew #oatmilk #austincoffee #smallbatch #austintx",
  "fixedFirstComment": null
}
```

`fixedFirstComment: null` means the first comment only held hashtags and can be deleted, because its
tags were merged into the 5 kept in the caption.

### Pricing

Pay per caption checked. With `onlyProblems` on, you pay only for captions that need changes.

# Actor input Schema

## `posts` (type: `array`):

Captions to check, as JSON: \[{"id": "post-1", "caption": "...", "firstComment": "..."}]. Plain strings also work. Hashtags in the first comment count toward the same limit.

## `captions` (type: `array`):

Optional. Single-line captions, one per line. Use Posts for captions with line breaks.

## `brandHashtags` (type: `array`):

Optional. Your branded hashtags; they are always kept in the fixed caption and count toward the limit.

## `maxHashtags` (type: `integer`):

Instagram's limit for posts and Reels has been 5 since December 2025. Change only if your account still has a different limit.

## `onlyProblems` (type: `boolean`):

Save (and pay for) only captions that break an Instagram rule (too many hashtags, too long, too many mentions, spam tags). Captions with only style tips are counted in the SUMMARY.

## Actor input object example

```json
{
  "posts": [
    {
      "id": "cold-brew-launch",
      "caption": "Sunday reset ☕ Our new oat milk cold brew is finally here! Smooth, low acid and made in small batches in Austin.\nWhich flavor should we drop next? Comment below 👇\n.\n.\n.\n#coffee #coldbrew #oatmilk #austincoffee #love #instagood #like4like #coffeeshop #smallbatch #photooftheday #coffeelover #austintx",
      "firstComment": "#coffeetime #latteart #specialtycoffee"
    },
    {
      "id": "monday",
      "caption": "I love #coffee and #mondays. Shop the beans: https://shop.example.com"
    }
  ],
  "maxHashtags": 5,
  "onlyProblems": false
}
```

# Actor output Schema

## `results` (type: `string`):

One row per caption: rule violations, tips, suggested hashtags and the fixed caption.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "posts": [
        {
            "id": "cold-brew-launch",
            "caption": "Sunday reset ☕ Our new oat milk cold brew is finally here! Smooth, low acid and made in small batches in Austin.\nWhich flavor should we drop next? Comment below 👇\n.\n.\n.\n#coffee #coldbrew #oatmilk #austincoffee #love #instagood #like4like #coffeeshop #smallbatch #photooftheday #coffeelover #austintx",
            "firstComment": "#coffeetime #latteart #specialtycoffee"
        },
        {
            "id": "monday",
            "caption": "I love #coffee and #mondays. Shop the beans: https://shop.example.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("feedwise/instagram-caption-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "posts": [
        {
            "id": "cold-brew-launch",
            "caption": """Sunday reset ☕ Our new oat milk cold brew is finally here! Smooth, low acid and made in small batches in Austin.
Which flavor should we drop next? Comment below 👇
.
.
.
#coffee #coldbrew #oatmilk #austincoffee #love #instagood #like4like #coffeeshop #smallbatch #photooftheday #coffeelover #austintx""",
            "firstComment": "#coffeetime #latteart #specialtycoffee",
        },
        {
            "id": "monday",
            "caption": "I love #coffee and #mondays. Shop the beans: https://shop.example.com",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("feedwise/instagram-caption-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "posts": [
    {
      "id": "cold-brew-launch",
      "caption": "Sunday reset ☕ Our new oat milk cold brew is finally here! Smooth, low acid and made in small batches in Austin.\\nWhich flavor should we drop next? Comment below 👇\\n.\\n.\\n.\\n#coffee #coldbrew #oatmilk #austincoffee #love #instagood #like4like #coffeeshop #smallbatch #photooftheday #coffeelover #austintx",
      "firstComment": "#coffeetime #latteart #specialtycoffee"
    },
    {
      "id": "monday",
      "caption": "I love #coffee and #mondays. Shop the beans: https://shop.example.com"
    }
  ]
}' |
apify call feedwise/instagram-caption-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,feedwise/instagram-caption-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/QHfExO3KgELaNCNBg/builds/YEVS7TsuXX7z0Qcoz/openapi.json
