REST API v1 — Production Ready

Build with the
Sharingtools API

Automate Instagram workflows programmatically. Manage accounts, schedule reposts, run engagement campaigns, and retrieve analytics — all through a single REST API.

80+
API Endpoints
1
Social Platform
60+
Automation Plugins
11
Languages

Platform Overview

Sharingtools is a multi-tenant SaaS platform for automating Instagram workflows. Built on a custom PHP framework with an event-driven plugin architecture, it gives users and agencies a single dashboard to manage dozens of accounts, schedule content, run engagement campaigns, and track performance.

The REST API exposes the platform's core functionality over HTTP so you can build custom integrations, automate account management, trigger campaigns programmatically, or pull data into your own analytics stack.

Multi-Account Management

List, inspect and control all connected social accounts. Check login status, proxy assignment, and automation state.

Repost Pro Automation

Configure repost schedules by hashtag, location, user, or direct post link. Control speed, captions, delays, and daily pause windows.

Reactions Pro Campaigns

Run like/follow/unfollow engagement campaigns with fine-grained speed control, daily limits, and per-account stats.

Caption Library

Create, read, update and delete saved captions and caption templates for use in automated publishing.

Post Scheduler

List and inspect posts by status: saved, scheduled, published, failed, or publishing. Query across all accounts.

Activity Logs

Retrieve per-account automation logs for Repost Pro and Reactions Pro with status details and timestamps.

Supported Platforms

Instagram

Primary platform. Full automation suite: repost, reactions, DMs, story repost, engagement, bulk operations.

Repost Pro Reactions DM Stories

Quick Start

Make your first API call in under 2 minutes.

1

Generate an API Key

Log in to your Sharingtools account and navigate to the API Keys panel. Click Generate New Key, give it a name, and copy the key — it starts with sht_. Store it securely; it is shown only once.

Go to API Keys panel →
2

Make Your First Request

Pass the key in the Authorization header as a Bearer token. Here's how to list all connected accounts:

curl
curl https://sharingtools.services/api/v1/accounts \
  -H "Authorization: Bearer sht_your_api_key_here" \
  -H "Accept: application/json"
3

Handle the Response

Every response is a JSON object with a status field ("success" or "error"). On success, data lives in data; on error, details are in message.

json
{
  "status": "success",
  "data": {
    "items": [
      {
        "id": 42,
        "username": "my_instagram_account",
        "platform": "instagram",
        "is_active": true,
        "login_required": false
      }
    ],
    "total": 1,
    "page": 1,
    "per_page": 20
  }
}

Authentication

All API endpoints require authentication. There are no public endpoints. Every request must carry a valid Bearer token.

Bearer Token

Include your API key in the HTTP Authorization header on every request:

http
Authorization: Bearer sht_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Property Detail
Prefixsht_ followed by 64 hex characters
HeaderAuthorization: Bearer <key>
StorageSHA-256 hash stored — raw key shown once on creation only
ScopeTied to the generating user account; can only access that user's data
RevocationKeys can be revoked any time from the API Keys panel
Admin keysKeys generated by an admin account have cross-user access where noted

Authentication Errors

HTTP StatusmessageCause
401UnauthorizedMissing or malformed Authorization header
401Invalid API keyKey not found or revoked
403Module not enabledYour plan does not include the requested module
403Admin access requiredAdmin-only endpoint accessed with a regular key

Base URL & Response Format

Base URL

url
https://sharingtools.services/api/v1/

Replace sharingtools.services with the domain of your Sharingtools installation.

Response Envelope

All responses are JSON. Every response shares this envelope:

json — success
{
  "status":  "success",          // always "success" or "error"
  "data":    { /* response payload */ }
}
json — error
{
  "status":  "error",
  "message": "Human-readable error description",
  "errors":  { /* optional field-level validation errors */ }
}

Request Format

MethodBody formatContent-Type header
GET, DELETEQuery string parameters onlyNot required
POST, PATCHJSON bodyapplication/json

Pagination

List endpoints return paginated results. Use query string parameters to navigate pages.

ParameterDefaultDescription
page1Page number (1-based)
per_page20Results per page (max 100)

Paginated responses always include these fields in data:

json
{
  "items":    [ /* array of results */ ],
  "total":    84,       // total matching records
  "page":     1,
  "per_page": 20
}

HTTP Status Codes & Errors

StatusMeaningCommon Cause
200OKRequest succeeded
201CreatedResource created (POST)
400Bad RequestMalformed JSON or missing required field
401UnauthorizedMissing, invalid, or revoked API key
403ForbiddenPlan does not include this module / admin only
404Not FoundResource ID does not exist or belongs to another user
409ConflictDuplicate resource (e.g. target already exists)
422Unprocessable EntityValidation failed — see errors object
503Service UnavailableRequired plugin/module not installed

Endpoint Reference

All paths are relative to /api/v1/. All requests require Bearer auth.

Accounts

Manage connected social media accounts. Scoped to the authenticated user.

MethodPathDescription
GET /accounts List all accounts. Filter by platform with ?platform=instagram
GET /accounts/{id} Get a single account by ID
GET /accounts/{id}/stats Account statistics (followers, following, posts count)
Example — GET /accounts
json — response
{
  "status": "success",
  "data": {
    "items": [
      {
        "id": 42,
        "username": "my_account",
        "full_name": "My Brand",
        "platform": "instagram",
        "is_active": true,
        "login_required": false,
        "is_slave": false,
        "proxy": "192.168.1.1:8080",
        "date": "2025-01-15 10:30:00"
      }
    ],
    "total": 5, "page": 1, "per_page": 20
  }
}

Captions

CRUD operations on the caption library. Captions are reusable text templates for automation.

MethodPathDescription
GET /captions List all captions (paginated). Filter with ?search=keyword
GET /captions/{id} Get a single caption by ID
POST /captions Create a new caption. Body: { title, caption }
PATCH /captions/{id} Update caption title or body
DELETE /captions/{id} Delete a caption permanently

Posts

Create, schedule, update, and delete posts. Use Media Upload to upload images/videos first, then reference the returned file IDs in media_ids.

MethodPathDescription
GET /posts List posts. Filter: ?status=scheduled|published|saved|failed&account_id=N
POST /posts Create a post or scheduled post. Body: account_id (required), caption, type, media_ids, is_scheduled, schedule_date
GET /posts/{id} Get a single post by ID
PATCH /posts/{id} Update a post (caption, schedule time, media). Cannot edit published posts.
DELETE /posts/{id} Delete a post
Post status values
StatusMeaning
savedDraft, not yet scheduled
scheduledQueued for future publication
publishingCurrently being sent to the platform
publishedSuccessfully published
failedPublication attempt failed

Media Upload

Upload images and videos to the platform's file storage. The returned id can be used as media_ids when creating or updating a post. Supports single uploads and multi-media carousels (comma-separate IDs).

MethodPathDescription
GET /media List your uploaded files (paginated)
POST /media Upload a new file — multipart/form-data, field name: file
GET /media/{id} Get metadata for a single file
DELETE /media/{id} Delete a file from storage
Upload details & scheduling workflow
DetailValue
Content-Typemultipart/form-datanot JSON
Field namefile
Allowed typesjpg, jpeg, png, mp4, gif (also mov, m4v, mpg if video processing is enabled)
Size limitEnforced per your plan's storage settings
Success responseHTTP 201 — returns file object with id, url, type, filesize

Schedule a post with an uploaded image:

bash
# Step 1 — upload the file
curl -X POST https://sharingtools.services/api/v1/media \
  -H "Authorization: Bearer sht_your_api_key" \
  -F "file=@/path/to/photo.jpg"
# → { "data": { "id": 42, "url": "...", "type": "image" } }

# Step 2 — create the scheduled post
curl -X POST https://sharingtools.services/api/v1/posts \
  -H "Authorization: Bearer sht_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": 7,
    "caption": "My caption here #hashtag",
    "type": "photo",
    "media_ids": "42",
    "is_scheduled": true,
    "schedule_date": "2026-03-28 14:00:00"
  }'

For a carousel, upload multiple files and comma-separate the IDs: "media_ids": "42,43,44"

Reactions Pro Module: reactions

Manage engagement campaigns (like/follow/unfollow automation). Requires the Reactions Pro module to be enabled on the account's package.

MethodPathDescription
GET/reactions/schedulesList all Reactions Pro schedules
GET/reactions/schedules/{account_id}Get schedule for a specific account
POST/reactions/schedules/{account_id}/activateActivate (resume) the schedule
POST/reactions/schedules/{account_id}/pausePause the schedule
GET/reactions/schedules/{account_id}/settingsGet all configurable settings
PATCH/reactions/schedules/{account_id}/settingsUpdate one or more settings
GET/reactions/targets/typesList all valid target type keys
GET/reactions/schedules/{account_id}/targetsList targets for an account
POST/reactions/schedules/{account_id}/targetsAdd a target to the schedule
DELETE/reactions/schedules/{account_id}/targets/{target_id}Remove a target
GET/reactions/logsList activity logs (all accounts)
GET/reactions/logs/{account_id}List activity logs for one account
GET/reactions/stats/{account_id}Engagement statistics for an account
POST/reactions/bulk/activateActivate schedules for multiple accounts at once
POST/reactions/bulk/pausePause schedules for multiple accounts
POST/reactions/bulk/stopForce-stop running schedules
Reactions Pro target types
TypeRequires ID/valueDescription
hashtaghashtag nameReact to posts with this hashtag
locationlocation IDReact to posts tagged at this location
peopleusernameReact to posts from followers of this user
exploreReact to posts in the Explore feed
feedReact to posts in the home feed
likerspost shortcodeReact to likers of a specific post
user_followersusernameFollow/unfollow followers of a user
user_followingusernameFollow/unfollow accounts this user follows

Repost Pro Module: repost-pro

Configure and control Repost Pro schedules — Instagram sources, speed, captions, and activity logs. Requires the Repost Pro module.

MethodPathDescription
GET/repost/schedulesList all Repost Pro schedules
GET/repost/schedules/{account_id}Get schedule for a specific account
POST/repost/schedules/{account_id}/activateActivate (resume) the schedule
POST/repost/schedules/{account_id}/pausePause the schedule
GET/repost/schedules/{account_id}/settingsGet all configurable settings
PATCH/repost/schedules/{account_id}/settingsUpdate one or more settings (partial)
GET/repost/targets/typesList all valid target type keys
GET/repost/schedules/{account_id}/targetsList repost sources for an account
POST/repost/schedules/{account_id}/targetsAdd a repost source (target)
DELETE/repost/schedules/{account_id}/targets/{target_id}Remove a repost source
GET/repost/logsList repost activity logs (all accounts)
GET/repost/logs/{account_id}List activity logs for one account
POST/repost/bulk/activateBulk activate schedules
POST/repost/bulk/pauseBulk pause schedules
Repost Pro target types (all 8)
TypeRequires valueDescription
hashtaghashtag nameRepost from Instagram hashtag (top/recent)
hashtag_reelshashtag nameRepost Reels from a hashtag
locationlocation IDRepost from tagged location
peopleusernameRepost from a user's followers' posts
people_reelsusernameRepost Reels from followers of a user
musicmusic IDRepost from posts using a specific music track
collectioncollection IDRepost from a saved Instagram collection
instagram_postpost URL or shortcodeRepost a specific Instagram post by URL
Settings fields for PATCH /repost/schedules/{id}/settings
FieldTypeDescription
Schedule
speedstringvery_slow | slow | medium | fast | very_fast
remove_delayintegerHours before auto-deleting the reposted content (0 = never)
daily_pausebooleanEnable daily pause window
daily_pause_fromstring HH:MMStart of pause window (e.g. "23:00")
daily_pause_tostring HH:MMEnd of pause window (e.g. "08:00")
Caption & Comment
captionstringCaption template (supports spintax)
first_commentstringAuto first comment text (supports spintax)
metadata_locationintegerLocation ID to tag on reposted media
metadata_userstringUsername to tag on reposted media
Advanced
collections_shufflebooleanShuffle collection order when reposting
data.photobooleanInclude photo posts
data.videobooleanInclude video posts
data.albumbooleanInclude album/carousel posts
data.reelsbooleanInclude Reel posts
data.private_onlybooleanOnly repost from private accounts (niche use)

Post Actions Module: post-actions-api

Queue and monitor automated like, comment, and follow actions on Instagram posts or profiles. Jobs are executed asynchronously by the cron engine. Requires the Post Actions API module.

MethodPathDescription
GET/post-actions/actionsList allowed action types
POST/post-actions/jobsCreate a new action job
GET/post-actions/jobsList all jobs (filter by ?status=)
GET/post-actions/jobs/{id}Get a single job by ID
DELETE/post-actions/jobs/{id}Cancel a pending job
GET/post-actions/logsList execution logs (filter by ?post_url=&action=)
GET/post-actions/logs/{id}Get per-account logs for a specific job
GET/post-actions/usageShow per-URL/action usage records
POST /post-actions/jobs — request body fields
FieldTypeRequiredDescription
post_urlstringYes (like/comment)Full Instagram post URL (/p/, /reel/, /tv/). For follow can be a post URL or profile URL.
target_usernamestringNofollow only — directly specify the username to follow (overrides post_url).
actionstringYeslike | comment | follow
countintegerYesNumber of accounts to perform the action (min 1).
comment_textstringcomment onlyText to post as comment. Supports spintax.
Job status values & lifecycle
StatusMeaning
pendingQueued, waiting for next cron run (scheduled ~1 min after creation)
processingCron is currently executing this job
successAll requested actions were performed successfully
partialSome accounts performed the action; others were skipped or failed
failedNo actions could be performed
cancelledJob was cancelled by the user before execution

Only pending jobs can be cancelled. Once a job reaches processing it cannot be stopped.

Example: create a like job
POST /api/v1/post-actions/jobs
Authorization: Bearer sht_your_key

{
  "post_url": "https://www.instagram.com/p/ABC123XYZ/",
  "action":   "like",
  "count":    10
}

// 201 Created
{
  "success": true,
  "data": {
    "id":           42,
    "post_url":     "https://www.instagram.com/p/ABC123XYZ/",
    "action":       "like",
    "count":        10,
    "comment_text": null,
    "status":       "pending",
    "scheduled_at": "2026-03-15T10:01:00Z",
    "created_at":   "2026-03-15T10:00:05Z"
  }
}
Example: follow by username
POST /api/v1/post-actions/jobs
Authorization: Bearer sht_your_key

{
  "target_username": "cristiano",
  "action":          "follow",
  "count":           5
}

// 201 Created — job queued for 5 accounts to follow @cristiano
Example: GET logs for a job
GET /api/v1/post-actions/logs/42
Authorization: Bearer sht_your_key

{
  "success": true,
  "data": [
    {
      "id":              88,
      "schedule_id":     42,
      "post_url":        "https://www.instagram.com/p/ABC123XYZ/",
      "action":          "like",
      "requested_count": 10,
      "performed_count": 9,
      "status":          "partial",
      "message":         "1 account skipped (already liked)",
      "details": {
        "results": [
          { "account_id": 7,  "username": "acct_one",  "status": "success" },
          { "account_id": 12, "username": "acct_two",  "status": "skipped", "reason": "already liked" }
        ]
      },
      "started_at":  "2026-03-15T10:01:12Z",
      "finished_at": "2026-03-15T10:01:48Z"
    }
  ]
}

Leads Finder Module: parser

Manage Instagram profile-scraping schedules and export the collected leads as paginated text. Supports 14 target types (followers, following, hashtags, locations, explore, and more). Requires the parser module.

MethodPathDescription
GET/leads/schedulesList all leads schedules (paginated)
GET/leads/schedules/{id}Get a single schedule by ID
POST/leads/schedules/{id}/startActivate schedule — sets is_active=1, schedule_date=now
POST/leads/schedules/{id}/stopStop schedule — sets is_active=0, is_running=0
GET/leads/schedules/{id}/exportExport collected leads (paginated lines from txt file)
GET/leads/logsList run logs (filter by ?account_id=&status=)
GET/leads/logs/{id}Get a single log entry
GET/leads/statsList parse stats (filter by ?account_id=&type=)
Schedule object fields
FieldTypeDescription
idintSchedule ID.
account_idintInstagram account ID this schedule belongs to.
task_namestringOptional task name set in the UI; used as the output file name.
statusstringrunning | active | scheduled | inactive
is_activeboolWhether the schedule is enabled.
is_runningboolWhether the cron is currently executing.
targetsarrayDecoded target objects (type, value, id).
target_countintNumber of targets in the array.
speedintSpeed setting (1–5).
estimated_speedintEstimated leads-per-hour calculated by cron.
estimated_speed_parsedintCumulative parsed count used for speed estimation.
analyzed_percentagefloatPercentage of target list analyzed so far (0–100).
parser_data_typestringWhich data type the cron collects (e.g. username).
data_fieldsobject15 boolean flags controlling which profile fields are written to the output file: nickname, user_id, user_link, full_name, is_business, business_category, city, link, profile_bio, followers_count, is_verified, home_country, whatsapp_number, is_new_to_instagram, is_new_to_instagram_30d.
filtersobjectProfile filters: followers_min/max, followings_min/max, posts_min/max, last_posted_min/max. 0 = no limit.
language_filterobjectlanguages (array of selected language objects), language_detection_notices (bool).
telegramobjectTelegram notifications: analytics_enabled, errors_enabled (bools), chat_id (int), delay (int seconds).
acceleratorsobjectenabled (bool), accounts (array), stop_if_all_disconnected (bool), per-action limits: get_followers_limit, get_following_limit, get_hashtag_limit, get_location_limit, get_liker_limit, get_info_limit.
custom_delaysobjectenabled (bool) + per-action delay in seconds: get_followers, get_following, get_hashtag, get_location, get_info, get_likers.
schedule_datestringDateTime of last start or next queue tick.
end_datestringEstimated completion DateTime.
last_action_datestringDateTime of last cron action.
Target types (14 supported)
TypeDescription
people_followersFollowers of a specific account
people_likersLikers of a specific post
people_followingAccounts followed by a specific account
people_followers_followingFollowing list of an account's followers
people_followers_followersFollowers of an account's followers
people_following_followersFollowers of accounts followed by the target
people_following_followingFollowing list of accounts followed by the target
hashtagUsers who posted under a hashtag
hashtag_likersLikers of posts under a hashtag
locationUsers who posted at a location
location_likersLikers of posts at a location
exploreUsers appearing in Explore feed
explore_likersLikers of posts in Explore feed
user_id_listCustom list of user IDs
Example: GET /leads/schedules response
GET /api/v1/leads/schedules
Authorization: Bearer sht_your_key

{
  "status": "success",
  "data": {
    "items": [
      {
        "id":                      12,
        "account_id":              7,
        "task_name":               "fashion-followers-march",
        "status":                  "active",
        "is_active":               true,
        "is_running":              false,
        "targets":                 [{"type":"people_followers","value":"fashionnova","id":"123456789"}],
        "target_count":            1,
        "speed":                   3,
        "estimated_speed":         480,
        "estimated_speed_parsed":  9600,
        "analyzed_percentage":     34.5,
        "parser_data_type":        "username",
        "data_fields": {
          "nickname": true, "user_id": false, "user_link": false,
          "full_name": true, "is_business": false, "business_category": false,
          "city": false, "link": false, "profile_bio": false,
          "followers_count": true, "is_verified": false, "home_country": false,
          "whatsapp_number": false, "is_new_to_instagram": false,
          "is_new_to_instagram_30d": false
        },
        "filters": {
          "followers_min": 500, "followers_max": 50000,
          "followings_min": 0,  "followings_max": 0,
          "posts_min": 3,       "posts_max": 0,
          "last_posted_min": 0, "last_posted_max": 90
        },
        "language_filter": {
          "languages": [], "language_detection_notices": false
        },
        "telegram": {
          "analytics_enabled": false, "errors_enabled": false,
          "chat_id": 0, "delay": 0
        },
        "accelerators": {
          "enabled": false, "accounts": [],
          "stop_if_all_disconnected": false,
          "get_followers_limit": 0, "get_following_limit": 0,
          "get_hashtag_limit": 0,   "get_location_limit": 0,
          "get_liker_limit": 0,     "get_info_limit": 0
        },
        "custom_delays": {
          "enabled": false,
          "get_followers": 0, "get_following": 0,
          "get_hashtag": 0,   "get_location": 0,
          "get_info": 0,      "get_likers": 0
        },
        "schedule_date":    "2026-03-15 10:00:00",
        "end_date":         "2200-12-12 23:59:59",
        "last_action_date": "2026-03-15 11:42:00"
      }
    ],
    "total": 1, "page": 1, "per_page": 20
  }
}
Example: GET /leads/schedules/{id}/export
GET /api/v1/leads/schedules/12/export?page=1&per_page=500
Authorization: Bearer sht_your_key

// 200 OK — paginated list of collected usernames:
{
  "status": "success",
  "data": {
    "items":    ["johndoe", "janesmith", "insta_user_99"],
    "total":    14872,
    "page":     1,
    "per_page": 500,
    "file_path": "data-parsed-by-fashionnova_acc.txt"
  }
}

// 404 if the parser has not produced a file yet:
{
  "status": "error",
  "message": "No exported leads file found for this schedule. The parser may not have run yet."
}

AI-DM Module: ai-dm

Manage AI-powered direct message schedules and browse conversation threads and messages. The AI-DM plugin uses OpenAI to generate contextual replies. Requires the ai-dm module.

MethodPathDescription
GET/ai-dm/schedulesList all AI-DM schedules (paginated)
GET/ai-dm/schedules/{id}Get a single schedule by ID
POST/ai-dm/schedules/{id}/activateActivate schedule — sets is_active=1
POST/ai-dm/schedules/{id}/pausePause schedule — sets is_active=0
GET/ai-dm/logsList run logs (filter by ?account_id=&type=&status=)
GET/ai-dm/logs/{id}Get a single log entry
GET/ai-dm/threadsList conversation threads (filter by ?account_id=)
GET/ai-dm/threads/{id}Get a single thread
GET/ai-dm/threads/{id}/messagesList messages in a thread (paginated, chronological)
Schedule object fields
FieldTypeDescription
idintSchedule ID.
account_idintInstagram account ID.
account_namestringInstagram username of the account (if stored).
statusstringrunning | active | inactive
is_activeboolWhether the schedule is enabled.
daily_pauseobjectenabled (bool), from (time string), to (time string).
ctaobjectCall-to-action: platform, username, spintax.
settings.system_promptstringSystem prompt given to the AI model.
settings.api_key_configuredbooltrue if an OpenAI API key is saved. The key itself is never returned.
settings.modelstringOpenAI model name (e.g. gpt-3.5-turbo).
settings.folderstringDM folder ID to scan (Instagram inbox folder).
settings.max_per_conversationintMax messages sent per conversation.
settings.max_per_day_requestsintMax conversation checks per day.
settings.max_per_run_requestsintMax conversation checks per cron run.
settings.max_per_day_messagesintMax messages sent per day.
settings.max_per_run_messagesintMax messages sent per cron run.
settings.max_timeintMax cron runtime in seconds.
schedule_datestringDateTime of last activation.
last_action_datestringDateTime of last cron action.
Thread and message object fields
Thread fieldTypeDescription
idintInternal thread record ID.
account_idintInstagram account ID that owns this thread.
thread_v2_idstringInstagram thread v2 identifier.
them_user_pkstringInstagram user PK of the other party.
them_usernamestringUsername of the other party.
them_fullnamestringFull name of the other party.
item_countintNumber of messages in the thread.
last_activity_atstringDateTime of most recent activity.
last_seen_by_usstringDateTime we last read this thread.
last_seen_by_themstringDateTime they last read this thread.
last_permanent_item_atstringDateTime of last permanent (non-ephemeral) message.
last_non_sender_item_atstringDateTime of last message not sent by us.
last_checkedstringDateTime when the AI last processed this thread.
Message fieldTypeDescription
idintInternal message record ID.
thread_idintParent thread ID.
item_idstringInstagram message item ID.
timestampstringMessage timestamp (microseconds, as stored by Instagram).
item_typestringInstagram item type (e.g. text, like, media_share).
is_sent_by_usbooltrue if our account sent this message.
contentobjectDecoded item_content JSON (text, media, etc.).
Example: GET /ai-dm/schedules and GET /ai-dm/threads/{id}/messages
GET /api/v1/ai-dm/schedules
Authorization: Bearer sht_your_key

// 200 OK
{
  "status": "success",
  "data": {
    "items": [{
      "id": 7,
      "account_id": 42,
      "account_name": "my_brand_account",
      "status": "active",
      "is_active": true,
      "daily_pause": { "enabled": false, "from": null, "to": null },
      "cta": { "platform": "whatsapp", "username": "+1234567890", "spintax": null },
      "settings": {
        "system_prompt": "You are a helpful brand assistant...",
        "api_key_configured": true,
        "model": "gpt-4",
        "folder": "0",
        "max_per_conversation": 5,
        "max_per_day_requests": 200,
        "max_per_run_requests": 50,
        "max_per_day_messages": 100,
        "max_per_run_messages": 25,
        "max_time": 300
      },
      "schedule_date": "2026-03-15 08:00:00",
      "last_action_date": "2026-03-15 14:32:11"
    }],
    "total": 1, "page": 1, "per_page": 20
  }
}

GET /api/v1/ai-dm/threads/3/messages?page=1&per_page=20
Authorization: Bearer sht_your_key

// 200 OK
{
  "status": "success",
  "data": {
    "items": [
      { "id": 101, "thread_id": 3, "item_id": "340282...", "timestamp": "1710505200000000",
        "item_type": "text", "is_sent_by_us": false, "content": { "text": "Hey, do you ship to EU?" } },
      { "id": 102, "thread_id": 3, "item_id": "340282...", "timestamp": "1710505260000000",
        "item_type": "text", "is_sent_by_us": true,  "content": { "text": "Yes! We ship worldwide. ..." } }
    ],
    "total": 2, "page": 1, "per_page": 20
  }
}

Welcome DM Module: welcomedm

Manage automated welcome direct message campaigns sent to new followers. Supports multiple message variants, daily pause windows, and attachment files. Requires the welcomedm module.

MethodPathDescription
GET/welcomedm/schedulesList all Welcome DM schedules (paginated)
GET/welcomedm/schedules/{id}Get a single schedule by ID
POST/welcomedm/schedules/{id}/activateActivate schedule — sets is_active=1
POST/welcomedm/schedules/{id}/pausePause schedule — sets is_active=0
GET/welcomedm/logsList run logs (filter by ?account_id=&status=)
GET/welcomedm/logs/{id}Get a single log entry
Schedule object fields
FieldTypeDescription
idintSchedule ID.
account_idintInstagram account ID this schedule belongs to.
is_activeboolWhether the schedule is enabled.
statusstringactive | inactive
messagesarrayDecoded array of message variant objects (text, optional media).
message_countintNumber of message variants configured.
speedint | stringDM send speed. "auto" (string) or an integer (1–5).
daily_pauseobjectenabled (bool), from (time string), to (time string).
settings.skip_openedboolSkip followers who have already opened a DM from us.
settings.mute_threadboolMute the thread after sending the welcome message.
settings.has_attachmentbooltrue if an attachment file is configured. File path is not exposed.
settings.debug_modeboolDebug mode — logs verbose output without sending real DMs.
schedule_datestringDateTime of last activation.
end_datestringScheduled end DateTime (if configured).
last_action_datestringDateTime of last cron action.
Example: GET /welcomedm/schedules
GET /api/v1/welcomedm/schedules
Authorization: Bearer sht_your_key

// 200 OK
{
  "status": "success",
  "data": {
    "items": [{
      "id": 3,
      "account_id": 42,
      "is_active": true,
      "status": "active",
      "messages": [
        { "text": "Hey {username}, welcome! 👋 Check our latest drops at {link}" },
        { "text": "Thanks for following! Use code WELCOME10 for 10% off 🎉" }
      ],
      "message_count": 2,
      "speed": "auto",
      "daily_pause": { "enabled": true, "from": "22:00", "to": "08:00" },
      "settings": {
        "skip_opened": true,
        "mute_thread": false,
        "has_attachment": false,
        "debug_mode": false
      },
      "schedule_date": "2026-03-10 09:00:00",
      "end_date": null,
      "last_action_date": "2026-03-15 14:45:00"
    }],
    "total": 1, "page": 1, "per_page": 20
  }
}

// Log entry:
GET /api/v1/welcomedm/logs/55
{
  "status": "success",
  "data": {
    "id": 55, "account_id": 42,
    "status": "sent",
    "follower_id": "9876543210",
    "message": null, "details": null,
    "date": "2026-03-15 14:45:00"
  }
}

Account Actions

Per-account and bulk Instagram account management operations sourced from PMPAccountsController. Includes credential refresh, proxy management, privacy toggling, 2FA backup codes, and settings management.

MethodPathDescription
POST/accounts/{id}/refresh-cookiesRe-login to Instagram and refresh the stored session cookies
GET/accounts/{id}/login-activityRetrieve recent login activity log for the account
POST/accounts/{id}/change-proxyAssign a new proxy to the account (auto-allocate from pool or provide proxy)
POST/accounts/change-proxy/bulkBulk proxy change for multiple accounts. Body: account_ids[]
POST/accounts/{id}/set-publicSet the Instagram account to public profile
POST/accounts/{id}/set-privateSet the Instagram account to private profile
GET/accounts/{id}/2fa-backupRetrieve 2FA backup codes from the connected Instagram account
DELETE/accounts/{id}/optionsReset/delete stored account options (engagement settings, action counts, etc.)
POST/accounts/{id}/passwordChange the stored Instagram password for this account
POST/accounts/password/bulkBulk password update. Body: [{account_id, password}] array
Request / response examples
// Refresh cookies
POST /api/v1/accounts/42/refresh-cookies
Authorization: Bearer sht_your_key
// 200 OK
{ "status": "success", "data": { "account_id": 42 }, "message": "Cookies refreshed." }

// Change proxy (auto-allocate)
POST /api/v1/accounts/42/change-proxy
Authorization: Bearer sht_your_key
// 200 OK
{ "status": "success", "data": { "account_id": 42, "proxy": "socks5://1.2.3.4:1080" }, "message": "Proxy updated." }

// Bulk change proxy
POST /api/v1/accounts/change-proxy/bulk
Authorization: Bearer sht_your_key
Content-Type: application/json
{ "account_ids": [42, 43, 44] }
// 200 OK
{ "status": "success", "data": { "updated": 3, "results": [
  { "account_id": 42, "proxy": "socks5://1.2.3.4:1080" },
  { "account_id": 43, "proxy": "socks5://5.6.7.8:1080" },
  { "account_id": 44, "proxy": "socks5://9.10.11.12:1080" }
]}}

// Set public
POST /api/v1/accounts/42/set-public
// 200 OK
{ "status": "success", "data": { "account_id": 42, "is_private": false }, "message": "Account set to public." }

// 2FA backup codes
GET /api/v1/accounts/42/2fa-backup
// 200 OK
{ "status": "success", "data": { "backup_codes": ["12345678","23456789","34567890"] }}

// Bulk password update
POST /api/v1/accounts/password/bulk
Content-Type: application/json
{ "accounts": [
  { "account_id": 42, "password": "newpass1" },
  { "account_id": 43, "password": "newpass2" }
]}
// 200 OK
{ "status": "success", "data": { "updated": 2 }, "message": "Passwords updated." }

First Comment Module: first-comment

Automatically post the first comment on target accounts' latest Instagram posts. Configure target accounts, comment pool, and rotation mode. Cron processes schedules every 5 minutes. Requires the first-comment module.

MethodPathDescription
GET/first-comment/schedulesList all schedules (filter: ?account_id=)
POST/first-comment/schedulesCreate a new schedule
GET/first-comment/schedules/{id}Get a single schedule by ID
PATCH/first-comment/schedules/{id}Update schedule targets, comments, or mode
DELETE/first-comment/schedules/{id}Delete a schedule permanently
POST/first-comment/schedules/{id}/activateActivate schedule — sets is_active=1
POST/first-comment/schedules/{id}/pausePause schedule — sets is_active=0
GET/first-comment/logsList all comment logs (paginated, filter: ?status=)
GET/first-comment/logs/{account_id}Logs filtered to a specific account
Schedule object fields
FieldTypeDescription
idintSchedule ID.
account_idintInstagram account that will post the comment.
is_activeboolWhether the schedule is enabled.
runningbooltrue if the cron is currently executing this schedule.
comment_modestringrandom | sequential — how comments are picked from the pool.
targetsarrayArray of {username, user_pk} objects — accounts whose posts to watch.
commentsarrayArray of comment strings (Spintax supported: {Hello|Hi|Hey}).
schedule_datestringDateTime the schedule next runs (or last activated).
last_action_datestringDateTime of the last cron action.
Example: Create schedule
POST /api/v1/first-comment/schedules
Authorization: Bearer sht_your_key
Content-Type: application/json
{
  "account_id": 42,
  "targets": [
    { "username": "nike", "user_pk": "19038780" },
    { "username": "adidas", "user_pk": "17841400" }
  ],
  "comments": [
    "Amazing! 🔥",
    "{Love|Great|Stunning} this post! 👏",
    "So inspiring! 💯"
  ],
  "comment_mode": "random",
  "is_active": true
}

// 201 Created
{
  "status": "success",
  "data": {
    "id": 12,
    "account_id": 42,
    "is_active": true,
    "running": false,
    "comment_mode": "random",
    "targets": [
      { "username": "nike", "user_pk": "19038780" },
      { "username": "adidas", "user_pk": "17841400" }
    ],
    "comments": ["Amazing! 🔥", "{Love|Great|Stunning} this post! 👏", "So inspiring! 💯"],
    "schedule_date": "2026-03-24 10:05:30",
    "last_action_date": "2026-03-24 10:05:30"
  },
  "message": "Schedule created."
}

InBox Module: inbox

Unified social inbox: read and reply to DMs, comments, and reviews across 13+ platforms (Instagram, Facebook, TikTok, WhatsApp, etc.) via the Zernio API. Thread IDs are compound strings encoding the local account, channel type, and remote identifier. Requires the inbox module.

Thread ID format: {account_id}_{channel_type}_{base64url(remote_thread_id)} — e.g. 42_dm_dF8xNzg0MTQ…. Always use the thread_id from list responses — do not construct IDs manually.
MethodPathDescription
GET/inbox/threadsList threads (filter: ?account_id=&channel_type=&status=&tag=&cursor=)
GET/inbox/threads/{id}Get a single thread with recent messages
POST/inbox/threads/{id}/replySend a reply in the thread. Body: {"content":"str"}
POST/inbox/threads/{id}/archiveArchive (hide) the thread
POST/inbox/threads/{id}/unarchiveUnarchive the thread
GET/inbox/tagsList all tags for the authenticated user
POST/inbox/tagsCreate a tag. Body: {"name":"str","color":"#hex"}
POST/inbox/threads/{id}/tagsAdd or remove tags on a thread. Body: {"add":[tag_id],"remove":[tag_id]}
Thread object fields
FieldTypeDescription
thread_idstringCompound thread ID (accountId_channelType_base64RemoteId).
account_idintLocal account ID this thread belongs to.
channel_typestringPlatform channel: dm, comment, review, etc.
participantsarrayArray of {id, username, avatar} participant objects.
unread_countintNumber of unread messages.
last_messageobjectPreview of the last message: {content_type, content, timestamp, is_sent_by_us}.
last_activity_atstringDateTime of last activity in the thread.
is_archivedboolWhether the thread is archived.
statusstringopen | closed | pending
tagsarrayArray of tag objects ({id, name, color}) attached to this thread.
Example: List threads & reply
// List threads
GET /api/v1/inbox/threads?channel_type=dm&status=open
Authorization: Bearer sht_your_key

// 200 OK
{
  "status": "success",
  "data": {
    "threads": [{
      "thread_id": "42_dm_dF8xNzg0MTQ3NzQ0NDc5Mg",
      "account_id": 42,
      "channel_type": "dm",
      "participants": [{ "id": "178414", "username": "john_doe", "avatar": null }],
      "unread_count": 2,
      "last_message": { "content_type": "text", "content": "Hey, is this available?", "timestamp": "2026-03-24T09:12:00Z", "is_sent_by_us": false },
      "last_activity_at": "2026-03-24T09:12:00Z",
      "is_archived": false,
      "status": "open",
      "tags": [{ "id": 3, "name": "VIP", "color": "#f59e0b" }]
    }],
    "next_cursor": "eyJpZCI6NDJ9",
    "total": 1
  }
}

// Reply in thread
POST /api/v1/inbox/threads/42_dm_dF8xNzg0MTQ3NzQ0NDc5Mg/reply
Content-Type: application/json
{ "content": "Yes, still available! DM us for details 🙌" }

// 200 OK
{ "status": "success", "data": { "thread_id": "42_dm_dF8xNzg0MTQ3NzQ0NDc5Mg", "sent": true }, "message": "Reply sent." }

Direct Basic Module: direct-basic

Native Instagram DM inbox management using the Instagram private API session directly. Read inbox and pending threads, retrieve messages with cursor-based pagination, and accept, decline, or delete pending DM requests. Requires the direct-basic module.

MethodPathDescription
GET/direct/{account_id}/inboxGet paginated DM inbox threads (params: cursor, folder 0=primary/1=general)
GET/direct/{account_id}/pendingGet pending (unaccepted) DM requests (param: cursor)
GET/direct/{account_id}/threads/{thread_id}/messagesGet messages in a thread (param: cursor for older messages)
POST/direct/{account_id}/threads/{thread_id}/acceptAccept a pending DM thread request
POST/direct/{account_id}/threads/{thread_id}/declineDecline (hide) a pending DM thread request
POST/direct/{account_id}/threads/{thread_id}/deleteDelete a DM thread from the inbox
Thread object fields
FieldTypeDescription
thread_idstringInstagram native thread ID (numeric string).
thread_titlestringThread title (usually the participant's username).
is_groupbooltrue for group DMs.
unread_countintNumber of unseen messages.
participantsarrayArray of {id, username} objects.
last_messageobject{type, timestamp, text} preview of the last message.
last_activityintUnix timestamp (microseconds) of last thread activity.
pendingbooltrue if the thread is in the pending requests inbox.
archivedbooltrue if the thread is pinned/archived.
Example: Get inbox & messages
// Get primary inbox
GET /api/v1/direct/42/inbox?folder=0
Authorization: Bearer sht_your_key

// 200 OK
{
  "status": "success",
  "data": {
    "threads": [{
      "thread_id": "340282366841710300949128224619416664029",
      "thread_title": "jane_smith",
      "is_group": false,
      "unread_count": 1,
      "participants": [{ "id": "9876543210", "username": "jane_smith" }],
      "last_message": { "type": "text", "timestamp": 1711270800000000, "text": "Hi, do you ship internationally?" },
      "last_activity": 1711270800000000,
      "pending": false,
      "archived": false
    }],
    "next_cursor": "QVFEZ...",
    "pending_count": 3
  }
}

// Get messages in thread
GET /api/v1/direct/42/threads/340282366841710300949128224619416664029/messages
// 200 OK
{
  "status": "success",
  "data": {
    "thread_id": "340282366841710300949128224619416664029",
    "messages": [{
      "id": "29:1",
      "type": "text",
      "timestamp": 1711270800000000,
      "user_id": "9876543210",
      "text": "Hi, do you ship internationally?",
      "is_sent_by_me": false
    }],
    "next_cursor": null
  }
}

// Accept pending thread
POST /api/v1/direct/42/threads/340282366841710300949128224619416664029/accept
// 200 OK
{ "status": "success", "data": { "thread_id": "340282366841710300949128224619416664029" }, "message": "Thread accepted." }

Rate Limits & Automation Speed

The REST API itself has no fixed per-IP rate limit, but the underlying automation engine enforces per-account execution rates controlled by the speed setting on each schedule. Setting a schedule to very_fast does not bypass Instagram's rate limits — it only affects how frequently the cron job processes that account.

Speed (Repost Pro)Speed (Reactions Pro)Approx. actions/hourRecommended for
very_slow1~5–10Aged accounts, cautious growth
slow2~20–30Default safe mode
medium3~50–70Active accounts
fast4~100–130High-volume campaigns
very_fast5~200+Short-term bursts only
Warning: Using fast or very_fast on new or unverified Instagram accounts significantly increases the risk of action blocks or permanent bans. Use a proxy per account and start new accounts on slow.

Ready to build?

Create a free account, generate your first API key from the dashboard, and start automating in minutes.

llms.txt