The Storrito API

The Storrito API allows to import images and videos that Storrito will post as Instagram Stories, Instagram Reels or TikTok posts. Furthermore it is possible to define Instagram Stickers that will be added to the story image or video.

The API is designed as 'HTTP API', meaning you can use curl and other HTTP clients to interact with the API and it will return common HTTP status codes. But the API is neither RESTful nor a full-blown remote-procedure-call service (like gRPC). The focus of the API design is to provide a good developer experience. Nowadays the best option might be to follow the OpenAPI specification, which allows to generate client SDKs for the most common programming languages. However, the downside is that OpenAPI and maintaining dozens of client SDKs is quite complex. For the moment we focus on providing a simple 'HTTP API' that is easy to use.

The API offers remote-procedure-calls (RPC) via HTTP. The arguments for the procedure are send as JSON via a HTTP POST request. All API endpoints starts with:

https://ORG_UUID.storrito.com/api/v1/

followed by the name of the procedure. Usually the response will also contain JSON data. The top-level data structure of the request and the response is always a map. This allows us to add more map entries without breaking your code.

Note: The URLs on this page contain ORG_UUID as a placeholder. Log in at storrito.com to see the URLs personalized with your organization's UUID.

No API or website has 100% availability, therefore be prepared to handle the following HTTP status codes and retry the HTTP request:

  • HTTP 429 'Too Many Requests': the API will return this status code to signal that you run into a rate limit. The default quota allows 60 requests per minute (using a token bucket algorithm). If the procedure has a stricter quota this will be mentioned in its documentation. A rate limit can also happen, when the API servers are too busy to accept further requests.
  • The API runs behind a HTTPs load balancer. When we deploy an update for the API the load balancer may return a HTTP 502, a HTTP 503 or a HTTP 504.

Retry the HTTP request either with an exponential backoff or just retry it every 2 seconds plus some random milliseconds (between 0-999ms).

Recommended rpc helper (Node.js)

Use this helper function for all API calls. It automatically retries on rate-limit (429) and transient server errors (502, 503, 504):

async function rpc(procedure, params = {}) {
  const maxAttempts = 5;
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(`${BASE_URL}/${procedure}`, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${TOKEN}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(params),
    });
    if ([429, 502, 503, 504].includes(res.status)) {
      if (attempt === maxAttempts) {
        throw new Error(`${procedure} failed after ${maxAttempts} attempts (${res.status})`);
      }
      const delay = 2000 + Math.random() * 1000;
      console.log(`${procedure}: HTTP ${res.status}, retrying in ${Math.round(delay)}ms...`);
      await new Promise((r) => setTimeout(r, delay));
      continue;
    }
    if (!res.ok) {
      const text = await res.text();
      throw new Error(`${procedure} failed (${res.status}): ${text}`);
    }
    return res.json();
  }
}
Story Components →

Web components for building Instagram Stories with HTML.

Use with AI Coding Agents

The Storrito API works great with AI coding agents like Claude Code, Cursor, GitHub Copilot, and others. You can paste the following example prompt into your agent to get started quickly:

Write a Node.js script that posts an image to Instagram Stories using the
Storrito API. Use the first connected Instagram account. Add a hashtag
sticker with "#travel" and a link sticker pointing to "https://example.com".

API docs: https://ORG_UUID.storrito.com/documentation/api/v1/index.md
Story component docs: https://ORG_UUID.storrito.com/documentation/api/v1/story-components.md

Base URL: https://ORG_UUID.storrito.com/api/v1/
Ask me for the bearer token before writing any code.

This is just a starting point. Customize the prompt to match your use case, for example by changing the sticker types, scheduling the post for a specific time, or using a video instead of an image.

Authentication

The API uses Bearer token authentication. You can create API credentials in your account settings under API Credentials.

When you create an API credential, a Bearer token is shown once. The server only stores a hash, so the token cannot be retrieved again.

Include the token in the Authorization header of every request:

Authorization: Bearer YOUR_BEARER_TOKEN

Store your token in a shell variable so you can copy-paste the curl examples below:

TOKEN="your-bearer-token-here"

Example using curl:

curl -X POST https://ORG_UUID.storrito.com/api/v1/PROCEDURE_NAME \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

This API is meant for server-to-server communication, please do not include Bearer tokens in client-side code.

A request without a valid token is answered with a HTTP 401 and the body:

{
  "errorMessage" : "not authenticated"
}

Validation

Each procedure call has a JSON schema that is used to validate the input parameters. An example:

The request:

curl -X POST https://ORG_UUID.storrito.com/api/v1/status-instagram-story \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"storyPostUud": "550e8400-e29b-41d4-a716-446655440000", "blah": true}'

Will result in a HTTP 400 response with the body:

{
  "errorMessage" : "invalid params for procedure: status-instagram-story",
  "procedureName" : "status-instagram-story",
  "paramsJsonSchema" : {
    "type" : "object",
    "properties" : {
      "storyPostUuid" : {
        "type" : "string",
        "format" : "uuid"
      }
    },
    "required" : [ "storyPostUuid" ],
    "additionalProperties" : false
  },
  "validationErrorExplanation" : {
    "storyPostUud" : [ "should be spelled :storyPostUuid" ],
    "blah" : [ "disallowed key" ]
  }
}

Besides an error message (errorMessage) the server will also show you the JSON schema (paramsJsonSchema) and explain why the parameters for the procedure are invalid (validationErrorExplanation). In the example above there is a typo in storyPostUud and the key blah is not defined for the procedure status-instagram-story.

Webhooks

Webhooks let Storrito notify your tools as soon as an Instagram Story post or a social post (Facebook, LinkedIn, Threads, Pinterest, Snapchat, ...) changes status. This is useful for no-code automations in Make, Zapier, n8n, Notion workflows, or your own backend because you do not need to poll status-instagram-story or status-social-post repeatedly.

Configure webhook URLs in the Storrito app under Storrito API → Webhooks. Each organization can configure up to 5 webhook URLs. Webhook URLs must use HTTPS. A webhook URL receives both events below; the event field and the X-Storrito-Event header tell them apart. URLs that were added before social post events existed receive Instagram Story events only; delete and add them again to also receive social post events.

Delivery behavior

Storrito sends an HTTP POST request with a JSON body. Your endpoint should return any 2xx HTTP status code to mark the delivery as successful. If the endpoint is unavailable or returns a non-2xx status code, Storrito retries the delivery with backoff and eventually marks it as failed.

For v1, webhook deliveries are intentionally simple and are not signed. Treat webhook payloads as notifications and call the API if your automation needs to verify the latest state.

Headers

Content-Type: application/json
X-Storrito-Event: instagram_story_post.status_changed
X-Storrito-Delivery: DELIVERY_UUID

X-Storrito-Event is instagram_story_post.status_changed or social_post.status_changed, the same value as the event field of the payload. X-Storrito-Delivery identifies the delivery and stays the same when Storrito retries it.

A retried delivery can arrive after a later status change of the same post. Use occurredAt to tell which status is the newest.

Test deliveries

Send test on the Webhooks page sends one instagram_story_post.status_changed payload with a random storyPostUuid, the status executed and "test": true to the URL, whichever events the URL receives. Use it to check that your endpoint is reachable; ignore payloads with "test": true in your automation. There is no test delivery for social_post.status_changed yet: schedule a social post for a future date and cancel it to receive a scheduled and a canceled payload.

Event: instagram_story_post.status_changed

This event is sent when an Instagram Story post changes status.

Possible status values:

  • scheduled — the story post was scheduled.
  • executed — the story was posted to Instagram.
  • failed — posting failed. The payload includes errorMessage.
  • canceled — the story post was canceled before it was posted.

Example payload:

{
  "event": "instagram_story_post.status_changed",
  "storyPostUuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "executed",
  "occurredAt": "2026-06-09T12:34:56Z"
}

Failed payload example:

{
  "event": "instagram_story_post.status_changed",
  "storyPostUuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "failed",
  "errorMessage": "Instagram returned an error.",
  "occurredAt": "2026-06-09T12:34:56Z"
}

Event: social_post.status_changed

This event is sent when a social post changes status, whether it was scheduled with schedule-social-post or on the scheduling page. status, errorMessage and permalink are the same as status-social-post returns at occurredAt.

Possible status values:

  • scheduled — the post was scheduled for a future date.
  • in-progress — the post was scheduled without a date or with a date in the past, so it is being published right away.
  • executed — the platform published the post. The payload includes permalink, when the platform reports one.
  • failed — posting failed. The payload includes errorMessage.
  • canceled — the post was canceled before it was published.

socialAccountId and platform are the ones list-social-accounts returns.

The event is sent when the post is scheduled and when it reaches its outcome (executed, failed or canceled). No event is sent when the date of a post scheduled for later arrives, so such a post goes from scheduled straight to its outcome; in-progress is only sent for a post scheduled without a date or with a date in the past.

Example payload:

{
  "event": "social_post.status_changed",
  "socialPostUuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "socialAccountId": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "platform": "LINKEDIN",
  "status": "executed",
  "permalink": "https://www.linkedin.com/feed/update/urn:li:share:7123456789",
  "occurredAt": "2026-06-09T12:34:56Z"
}

Errors

All 'expected' errors will return a HTTP 400 status code. Unexpected errors are caused by bugs or downtimes on the server-side, they will return a HTTP 500 status code. These errors should only be retried, if the procedure is idempotent.

Using standard HTTP status codes is the reason why we call the design an 'HTTP API' and one of the reason we do not use JSON-RPC.

Dates

All dates in the API use ISO 8601 format in UTC (e.g. "2025-06-15T14:30:00Z"). Most languages have built-in support for parsing and formatting ISO 8601 date-time strings.

Instagram Limits and Best Practices

Instagram enforces its own limits that are outside of Storrito's control. Violating them can result in temporary posting blocks or automation warnings on your account.

Posting frequency

  • Instagram allows roughly 15–25 stories per account per day. Exceeding this may trigger a temporary cooldown or a "try again later" error.
  • Space out your posts. Avoid bursting many stories for the same account within a few minutes.
  • The Storrito API enforces its own per-account quota (100 story posts per account per 24 hours) as a safety net, but Instagram's limits are lower and less predictable.

Content uniqueness

  • Do not post the same story design repeatedly. Instagram's systems detect duplicate content and may flag your account for spam or automation.
  • Each story should have a unique visual — change the background image or video, sticker text, or layout between posts.
  • If you are testing your integration, preview your story locally using the <insta-story> web components in a browser instead of posting to Instagram repeatedly.

Account health

  • If Instagram returns an error or blocks a post, back off and wait before retrying. Do not retry failed posts in a tight loop.

Social Post Limits

Each connected social account (see list-social-accounts) can publish a limited number of posts per day. The limit belongs to the account on the platform and counts every post Storrito publishes on it, whether scheduled with schedule-social-post or in Storrito, and also when the same account is connected to several Storrito organizations. A day is a UTC calendar day, and a post counts on the day of its date. Keep your posting below the limit.

PlatformPosts per day and account
Facebook50
LinkedIn18
Pinterest24
Snapchat20
Threads200
TikTok10
X15
YouTube10

Video Requirements

When your design contains a video, the API validates it before rendering. Videos that do not meet the following requirements are rejected with an HTTP 400 error and a descriptive message.

  • Codec: H.264 (h264)
  • Resolution: 1080 x 1920 pixels (9:16 portrait)
  • Duration: Instagram Story 0.5 – 60 seconds, Instagram Reel 0.5 – 180 seconds; other post types minDurationSeconds – maxDurationSeconds from list-social-accounts
  • Bitrate: ≤ 30 Mbps

A temp-blob (create-temp-blob-upload-url) holds at most 100 MB. Host a larger video at a public URL and reference that URL instead.

Converting a video with ffmpeg

Use the following ffmpeg command to convert any video to the required format:

ffmpeg -i input.mov \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" \
  -c:v libx264 -crf 18 -r 30 \
  -c:a aac -b:a 128k \
  -movflags +faststart \
  -t 60 \
  output.mp4

What this does:

  • scale=1080:1920:...,pad=1080:1920:... — scales the video to fit within 1080×1920 while keeping the aspect ratio, then pads with black bars to exactly 1080×1920.
  • -c:v libx264 -crf 18 — encodes with H.264 at high quality. Increase the CRF value (e.g. 23) for a smaller file size.
  • -r 30 — sets 30 fps.
  • -c:a aac -b:a 128k — encodes audio as AAC at 128 kbps.
  • -movflags +faststart — moves the MP4 metadata to the beginning for faster HTTP streaming.
  • -t 60 — caps the video at 60 seconds, the limit of an Instagram Story. Raise it to the maxDurationSeconds of other post types.

After conversion, verify the result with:

ffprobe -v quiet -print_format json -show_streams output.mp4

Check that the video stream shows "codec_name": "h264", "width": 1080, "height": 1920, and "bit_rate" below 30000000.

The API procedures

Please find below the procedures that are offered to automate your Storrito account:

cancel-instagram-reel

Cancels a scheduled Instagram reel before it is posted.

Provide the reelPostUuid that was returned by the schedule-instagram-reel procedure.

  • If the reel is still scheduled, it will be canceled and the response status will be canceled.
  • If the reel was already canceled, the response status will be canceled (idempotent).
  • If posting already started, succeeded, or failed, an error is returned because the reel cannot be canceled anymore.
    curl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-instagram-reel \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"reelPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
    
{
  "reelPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

cancel-instagram-story

Cancels a scheduled Instagram story post before it is posted.

Provide the storyPostUuid that was returned by the schedule-instagram-story procedure.

  • If the story is still scheduled, it will be canceled and the response status will be canceled.
  • If the story was already canceled, the response status will be canceled (idempotent).
  • If the story was already executed or failed, an error is returned because it cannot be canceled.
    curl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-instagram-story \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"storyPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
    
{
  "storyPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

cancel-social-post

Cancels a scheduled social post before it is published.

Provide the socialPostUuid that was passed to schedule-social-post.

  • If the post is still scheduled or in progress, it will be canceled and the response status will be canceled. A post that is in-progress may already be on its way to the platform: a cancel in the last moments before or after its date may come too late to stop the publication, like a cancel in the Storrito app.
  • If the post was already canceled, the response status will be canceled (idempotent).
  • If the post was already executed or failed, an error is returned because it cannot be canceled.
  • If Storrito is uploading the post to the platform at that moment, or the platform could not be reached, an HTTP 429 error is returned. Retry after a minute; the post is not canceled until a retry succeeds.
    curl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-social-post \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"socialPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
    
{
  "socialPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

cancel-tiktok-post

Cancels a scheduled TikTok post before it is posted.

Provide the tiktokPostUuid that was returned by the schedule-tiktok-post procedure.

  • If the post is still scheduled or in progress, it will be canceled and the response status will be canceled.
  • If the post was already canceled, the response status will be canceled (idempotent).
  • If the post was already executed or failed, an error is returned because it cannot be canceled.
    curl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-tiktok-post \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"tiktokPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
    
{
  "tiktokPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

create-draft

Renders a page built with <insta-story> web components and puts it into the Storrito gallery as a draft, without scheduling it.

Use it when a person should approve the design first: the draft shows up in the gallery of the Storrito app, where it can be opened in the editor, changed, and scheduled by hand as an Instagram story, an Instagram reel or a TikTok post. Nothing is posted by this procedure.

Provide either the url of your hosted page or pass the HTML directly via the html parameter. Exactly one of url or html must be provided. The HTML format, the sticker components, the layout advice and the sandboxing are the same as for schedule-instagram-story. A video may be up to 60 seconds long.

Optionally provide a name that the gallery shows for the draft, and a folderName to put the draft into a top-level gallery folder (created when it does not exist yet), so that all drafts of your integration end up in one place.

Unknown JSON keys are rejected. This prevents typos from being silently ignored.

Every request requires a draftUuid that you generate on your side. This ensures idempotency — if a draft with that UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests.

The response contains an editorUrl that opens the draft in the Storrito editor. Send it to the person who reviews the draft; it requires a login to the Storrito workspace.

Preview: Rendering starts right after the draft was created. As soon as it has finished (usually within a minute), status-draft returns a previewUrl: a JPEG of the rendered design with background, text and stickers.

Warnings: Unknown <insta-*> elements and unknown attributes on sticker elements are ignored, but reported in the warnings array of the response, and so are stickers that overlap each other. The draft is created anyway. If a warning names something you meant to use, delete the draft with delete-draft and create it again with the corrected HTML.

Mentions: Resolving an <insta-mention> username uses one of your connected Instagram accounts. If all of them are busy with another request at that moment, the request fails with HTTP 429. Retry it later with the same draftUuid.

Quota: A maximum of 100 drafts can be created in any rolling 24-hour window. Deleted drafts count as well.

Request duration: Before the request returns, the server loads your page in a headless browser, extracts the sticker data and uploads the media. This can take longer than 30 seconds, so configure a client read timeout of at least 120 seconds. If your client times out anyway, retry with the same draftUuid.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/create-draft \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "html": "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;padding:300px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px\"><insta-hashtag hashtag=\"travel\"></insta-hashtag></div></insta-story>",
       "draftUuid": "3bda1520-e453-4307-a47c-16e6f4070704",
       "name": "Travel promo",
       "folderName": "API drafts"
     }'
   
{
  "html" : "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;padding:300px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px\"><insta-hashtag hashtag=\"travel\"></insta-hashtag></div></insta-story>",
  "draftUuid" : "3bda1520-e453-4307-a47c-16e6f4070704",
  "name" : "Travel promo",
  "folderName" : "API drafts"
}

create-temp-blob-upload-url

Creates a presigned upload URL for a temporary media blob (image, video or audio, max 100 MB), for media that only exists as a local file — media that already has a public URL can be referenced in the story html directly and needs no temp-blob. PUT the file to the returned uploadUrl — the bytes go directly to storage, no base64 anywhere:

curl -X POST https://ORG_UUID.storrito.com/api/v1/create-temp-blob-upload-url \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tempBlobUuid": "3bda1520-e453-4307-a47c-16e6f4070704", "contentType": "video/mp4", "contentLengthBytes": '$(stat -c%s story.mp4)'}'

curl -T story.mp4 -H "Content-Type: video/mp4" "UPLOAD_URL"

Afterwards use the stable url from the result as the src inside the html of schedule-instagram-story, schedule-instagram-reel, schedule-tiktok-post or schedule-social-post, and to preview the media in a browser (a GET redirects to a short-lived download URL), for example:

<insta-story><img src="TEMP_BLOB_URL"></insta-story>

Temp-blobs are deleted automatically about a day after the upload — schedule the post within 24 hours.

{
  "tempBlobUuid" : "5f0a97b2-4c31-4f5e-9b6d-2a8c0e7d1f43",
  "contentType" : "video/mp4",
  "contentLengthBytes" : 8388608
}

delete-draft

Deletes a draft that was created by create-draft. The draft disappears from the Storrito gallery.

Provide the draftUuid that was passed to create-draft.

  • If the draft still exists, it is deleted and the response status is deleted.
  • If the draft was already deleted, the response status is deleted as well (idempotent).
  • If a user has already scheduled or posted the draft, an error is returned. Cancel the post in the Storrito app first.

When a user edited the draft in the Storrito editor, the latest saved version is deleted.

Use it to replace a draft: delete it and call create-draft again with a new draftUuid and the corrected HTML. A deleted draft still counts for the draft quota.

curl -X POST https://ORG_UUID.storrito.com/api/v1/delete-draft \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"draftUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
{
  "draftUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

generate-uuid

Generates a random UUID. Useful for creating a storyPostUuid before calling schedule-instagram-story or a tiktokPostUuid before calling schedule-tiktok-post.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/generate-uuid \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{}'
   
{ }

list-instagram-users

Lists all Instagram users connected to your Storrito account.

Returns an array of Instagram users with their username, numeric ID, and linked Facebook destinations. Only active (non-deleted) accounts are included. Use the instagramUsername value when calling schedule-instagram-story. Pass shareToFacebook: true and, when needed, one of the returned facebookDestinationId values to cross-post a Story to Facebook.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/list-instagram-users \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{}'
   
{ }

list-social-accounts

Lists all social accounts connected to your Storrito account: Instagram, TikTok, YouTube, Facebook, LinkedIn, Pinterest, Snapchat, Threads, X and every other platform Storrito connects.

Each account lists its postTypes: what can be posted (postType), the API procedure that schedules it, whether a video or an image, the duration limits and whether the caption is published. Call the procedure with the account's ID field:

  • schedule-social-post: pass socialAccountId and the postType; options lists the options of the post type.
  • schedule-instagram-story and schedule-instagram-reel: pass instagramUsername. An Instagram account lists the facebookDestinations a Story can be cross-posted to (shareToFacebook and facebookDestinationId of schedule-instagram-story).
  • schedule-tiktok-post: pass tiktokAccountId.

A TikTok account can show up twice: connected directly (schedule-tiktok-post) and through Storrito's social integrations (schedule-social-post). A YouTube channel that is connected directly has no postTypes, since the API cannot post to it yet. disconnected is true when the account must be reconnected in the Storrito app before posts can be scheduled.

curl -X POST https://ORG_UUID.storrito.com/api/v1/list-social-accounts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
{ }

list-tiktok-accounts

Lists all TikTok accounts connected to your Storrito account.

Returns an array of TikTok accounts with their display name and account ID. Use the tiktokAccountId value when calling schedule-tiktok-post.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/list-tiktok-accounts \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{}'
   
{ }

schedule-instagram-reel

Renders a page built with <insta-story> web components and schedules the rendered video as an Instagram reel.

Provide either the url of your hosted page or pass the HTML directly via the html parameter, plus the instagramUsername to post to. Exactly one of url or html must be provided.

When using html, the server injects the web component JavaScript and fonts automatically — just provide the raw HTML containing your <insta-story> markup. The HTML is loaded in a sandboxed context with no origin (about:blank), so it cannot access cookies or session data.

Instagram reels must be videos, so the <insta-story> element needs a src attribute that points to a video. The video can be up to 3 minutes long. Any other components on the page are rendered into the video. Instagram-native sticker metadata is not available for reels.

Optionally provide a date (ISO 8601 string, e.g. "2025-06-15T14:30:00Z") to schedule the reel for a future time. When date is omitted the reel is published as soon as rendering is complete.

Optionally provide a caption, set shareToFeed to also share the reel to the account's main feed, or set aiGenerated to mark the reel as AI-generated content.

The server creates the same editor2-compatible story-media that is used by schedule-instagram-story, so the reel can be opened and edited in the Storrito editor. The Instagram account must be connected in your Storrito dashboard first.

Every request requires a reelPostUuid that you generate on your side. This ensures idempotency — if a reel with that UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests. Pass the UUID to the status-instagram-reel procedure to poll for the posting status.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-instagram-reel \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "html": "<insta-story src=\"https://example.com/my-reel.mp4\"></insta-story>",
       "instagramUsername": "YOUR_INSTAGRAM_USERNAME",
       "reelPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704",
       "caption": "My first reel via the Storrito API"
     }'
   
{
  "html" : "<insta-story src=\"https://example.com/my-reel.mp4\"></insta-story>",
  "instagramUsername" : "YOUR_INSTAGRAM_USERNAME",
  "reelPostUuid" : "3bda1520-e453-4307-a47c-16e6f4070704",
  "caption" : "My first reel via the Storrito API"
}

schedule-instagram-story

Renders a page built with <insta-story> web components and schedules it as an Instagram story.

Provide either the url of your hosted story page or pass the HTML directly via the html parameter, plus the instagramUsername to post to. Exactly one of url or html must be provided.

When using html, the server injects the web component JavaScript and fonts automatically — just provide the raw HTML containing your <insta-story> markup. The HTML is loaded in a sandboxed context with no origin (about:blank), so it cannot access cookies or session data.

Optionally provide a date (ISO 8601 string, e.g. "2025-06-15T14:30:00Z") to schedule the story for a future time. When date is omitted the story is posted immediately.

Optionally set aiGenerated to true to mark the story as AI-generated content, so Instagram shows its AI label on the story.

Optionally set shareToFacebook to true to cross-post the Story to a Facebook destination linked to the selected Instagram account. If the account has multiple Facebook destinations, pass facebookDestinationId; otherwise Storrito uses the first linked destination.

Unknown JSON keys are rejected. This prevents typos from being silently ignored.

The server extracts sticker data from the page, builds an editor2-compatible design, and schedules the story for rendering and posting. The resulting story can be opened and edited in the Storrito editor. The Instagram account must be connected in your Storrito dashboard first.

Every request requires a storyPostUuid that you generate on your side. This ensures idempotency — if a story post with that UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests. Pass the UUID to the status-instagram-story procedure to poll for the posting status.

Request duration: Before the request returns, the server loads your page in a headless browser, extracts the sticker data and uploads the media. Depending on server load and media size (especially for video stories) this can take longer than 30 seconds, so configure a client read timeout of at least 120 seconds. If your client times out anyway, the server usually still finishes the request — retry with the same storyPostUuid: thanks to idempotency the retry returns the success response without creating a duplicate.

Extracting stickers: Any <insta-hashtag>, <insta-mention>, <insta-location>, <insta-link>, or other sticker components on the page are automatically extracted and applied as native Instagram stickers. Unknown <insta-*> elements and unknown attributes on sticker elements are ignored, but reported in the warnings array of the response, and so are stickers that overlap each other. The story is scheduled anyway, so check warnings: if one names something you meant to use or a layout you did not intend, cancel the story with cancel-instagram-story and schedule it again with the corrected HTML.

Mentions: Resolving an <insta-mention> username uses one of your connected Instagram accounts. If all of them are busy with another request at that moment (e.g. a story being posted), the request fails with HTTP 429. Retry it later with the same storyPostUuid.

Layout: Put all stickers into one flex column (display:flex;flex-direction:column;align-items:center;gap:40px on a layer over the whole canvas, with padding:300px 40px for Instagram's safe zone) and let the browser space them. Sticker sizes depend on their text, so hand-picked top values for absolutely positioned stickers overlap easily; pill stickers alone are 177px tall.

Video stories: If the <insta-story> element has a src attribute pointing to a video, a video story is created. Otherwise an image story is created.

Preview: Rendering starts right after scheduling, also for stories with a future date. As soon as it has finished (usually within a minute), status-instagram-story returns a previewUrl: a JPEG of the rendered story with background, text and stickers (the full-size image for image stories, a 360x640 first frame for video stories). Check it while the status is still scheduled. If a sticker looks wrong, cancel the story with cancel-instagram-story and schedule it again with the corrected HTML.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-instagram-story \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "html": "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;padding:300px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px\"><insta-hashtag hashtag=\"travel\"></insta-hashtag><insta-link url=\"https://example.com\" text=\"Shop Now\"></insta-link></div></insta-story>",
       "instagramUsername": "YOUR_INSTAGRAM_USERNAME",
       "storyPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"
     }'
   

Component reference. Attribute names are exact and there is no <insta-text>: write text as plain HTML (<p>, <h1>, ...). Every <insta-*> element needs an explicit closing tag (custom elements cannot be self-closing).

  • <insta-story>: attributes src. Example: <insta-story src="https://assets.mixkit.co/videos/1164/1164-1080.mp4"></insta-story>
  • <insta-hashtag>: attributes hashtag, design (default/gray/rainbow). Example: <insta-hashtag hashtag="summer" design="gray"></insta-hashtag>
  • <insta-mention>: attributes username, design (default/gray/rainbow). Example: <insta-mention username="johndoe" design="gray"></insta-mention>
  • <insta-location>: attributes location, location-id, design (default/gray/black/orange/rainbow). Example: <insta-location location="Berlin" design="gray"></insta-location>
  • <insta-link>: attributes url, text, design (default/gray/black/rainbow). Example: <insta-link url="https://example.com" text="Shop Now" design="gray"></insta-link>
  • <insta-poll>: attributes question, options, color (black/pink/lavender/purple/orange/green/blue). Example: <insta-poll question="Beach or Mountains?" options='["Beach", "Mountains"]' color="pink"></insta-poll>
  • <insta-question>: attributes question, color (white/black/pink/lavender/purple/orange/green/blue). Example: <insta-question question="Ask me anything!" color="white"></insta-question>
  • <insta-quiz>: attributes question, options, correct-answer. Example: <insta-quiz question="Capital of France?" options='["London", "Paris", "Berlin", "Madrid"]' correct-answer="1"></insta-quiz>
  • <insta-countdown>: attributes title, end-time, color (black/white/purple/red/orange/yellow/green/blue). Example: <insta-countdown title="LAUNCH DAY" end-time="2026-06-15T12:00:00" color="red"></insta-countdown>
  • <insta-emoji-slider>: attributes question, emoji, color, text-color. Example: <insta-emoji-slider question="How much do you like pizza?" emoji="🍕" color="#ffffff" text-color="#000000"></insta-emoji-slider>

The full reference with key concepts (layout, safe zone, sticker sizes, fonts) is at https://storrito.com/documentation/api/v1/story-components.md (MCP clients: call the get-story-components-reference tool).

{
  "html" : "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;padding:300px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px\"><insta-hashtag hashtag=\"travel\"></insta-hashtag><insta-link url=\"https://example.com\" text=\"Shop Now\"></insta-link></div></insta-story>",
  "instagramUsername" : "YOUR_INSTAGRAM_USERNAME",
  "storyPostUuid" : "3bda1520-e453-4307-a47c-16e6f4070704"
}

schedule-social-post

Renders a page built with <insta-story> web components and schedules the rendered media as a post on a social account that is connected through Storrito's social integrations: a Facebook reel or story, a LinkedIn post, a Pinterest pin, a Snapchat story or Spotlight, a Threads post, an X post (a caption with a link costs more on X), and the other platforms that list-social-accounts lists.

Provide either the url of your hosted page or pass the HTML directly via the html parameter. Exactly one of url or html must be provided. The HTML format, the sticker components and the sandboxing are the same as for schedule-instagram-story; the platform receives the rendered video or image, Instagram-native sticker metadata is not sent.

Use list-social-accounts to find the socialAccountId and the postType values of an account. A design without video renders as an image, a design with video as a video; the post type must take what the design renders as (see media of the post type). Videos are checked against the post type's duration limits (minDurationSeconds and maxDurationSeconds in list-social-accounts, the limits of the platform); the source video itself must fit them. Unknown <insta-*> elements and attributes and overlapping stickers are reported in warnings; the post is scheduled anyway.

text is the caption: it is shortened to the post type's maxCaptionLength, and LinkedIn requires one. options sets the post type's options by their key, e.g. {"privacy": "CONNECTIONS"} for a LinkedIn post or {"title": "Summer sale", "link": "https://example.com"} for a Pinterest pin.

Optionally provide a date (ISO 8601 string, e.g. "2025-06-15T14:30:00Z") to schedule the post for a future time. When date is omitted the post is published as soon as rendering is complete.

Request duration: Before the request returns, the server loads your page in a headless browser and uploads the media. Depending on server load and media size (especially for videos) this can take longer than 30 seconds, so configure a client read timeout of at least 120 seconds. If your client times out anyway, the server usually still finishes the request — retry with the same socialPostUuid: thanks to idempotency the retry returns the success response without creating a duplicate.

Every request requires a socialPostUuid that you generate on your side. This ensures idempotency — if a post with that UUID already exists, the same success response is returned without creating a duplicate, whatever the other parameters are (except a different socialAccountId, which is an error); the response then carries the post's current status, like status-social-post. Pass the UUID to status-social-post to poll for the posting status, or to cancel-social-post to cancel the post. The social_post.status_changed webhook (see Webhooks) carries the same UUID, so you can also wait for its status changes instead of polling.

curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-social-post \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div></insta-story>",
    "socialAccountId": "YOUR_SOCIAL_ACCOUNT_ID",
    "socialPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704",
    "postType": "POST",
    "text": "Hello from the Storrito API"
  }'
{
  "html" : "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div></insta-story>",
  "socialAccountId" : "YOUR_SOCIAL_ACCOUNT_ID",
  "socialPostUuid" : "3bda1520-e453-4307-a47c-16e6f4070704",
  "postType" : "POST",
  "text" : "Hello from the Storrito API"
}

schedule-tiktok-post

Renders a page built with <insta-story> web components and schedules the rendered media as a TikTok post. A video may be up to 600 seconds long; TikTok may allow less for some accounts, then the post fails when it is published.

Provide either the url of your hosted story page or pass the HTML directly via the html parameter, plus the tiktokAccountId to post to. Exactly one of url or html must be provided.

When using html, the server injects the web component JavaScript and fonts automatically — just provide the raw HTML containing your <insta-story> markup. The HTML is loaded in a sandboxed context with no origin (about:blank), so it cannot access cookies or session data.

Optionally provide a date (ISO 8601 string, e.g. "2025-06-15T14:30:00Z") to schedule the TikTok post for a future time. When date is omitted the post is published as soon as rendering is complete.

For rendered image/photo posts, TikTok allows title to be at most 90 characters. Put longer text into description.

The server creates the same editor2-compatible story-media that is used by schedule-instagram-story. TikTok receives the rendered image or video; Instagram-native sticker metadata is not sent to TikTok.

Every request requires a tiktokPostUuid that you generate on your side. This ensures idempotency — if a TikTok post with that UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests. Pass the UUID to the status-tiktok-post procedure to poll for the posting status.

Use list-tiktok-accounts to find the tiktokAccountId of a connected account.

   curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-tiktok-post \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "html": "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;padding:300px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px\"><insta-hashtag hashtag=\"travel\"></insta-hashtag><insta-mention username=\"storrito\"></insta-mention></div></insta-story>",
       "tiktokAccountId": "YOUR_TIKTOK_ACCOUNT_ID",
       "tiktokPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"
     }'
   
{
  "html" : "<insta-story><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;background:#1a1a2e\"></div><div style=\"position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;padding:300px 40px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px\"><insta-hashtag hashtag=\"travel\"></insta-hashtag><insta-mention username=\"storrito\"></insta-mention></div></insta-story>",
  "tiktokAccountId" : "YOUR_TIKTOK_ACCOUNT_ID",
  "tiktokPostUuid" : "3bda1520-e453-4307-a47c-16e6f4070704"
}

status-draft

Returns the current status of a draft that was created by create-draft.

Provide the draftUuid that was passed to create-draft. The response includes a status field:

  • rendering — the draft is in the gallery, its preview is not rendered yet.
  • ready — the draft is rendered. The previewUrl field contains a JPEG of the rendered design.
  • failed — the rendering failed for good. Delete the draft with delete-draft and create it again.
  • deleted — the draft was deleted, in the Storrito app or via delete-draft.

Rendering starts right after create-draft and usually finishes within a minute. Poll until the status is ready and check the previewUrl. If something looks wrong, delete the draft with delete-draft and create it again with corrected HTML.

When a user edits the draft in the Storrito editor, this procedure follows the edit: status, previewUrl and editorUrl describe the latest saved version.

curl -X POST https://ORG_UUID.storrito.com/api/v1/status-draft \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"draftUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
{
  "draftUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

status-instagram-reel

Returns the current posting status of an Instagram reel.

Provide the reelPostUuid that was returned by the schedule-instagram-reel procedure. The response includes a status field:

  • scheduled — the reel is queued or its video is still rendering.
  • in-progress — the reel is due and being processed.
  • executed — the reel has been posted to Instagram.
  • failed — posting failed. The errorMessage field contains details.
  • canceled — the reel was canceled before it was posted.

Call this procedure repeatedly to poll until the status is executed or failed.

curl -X POST https://ORG_UUID.storrito.com/api/v1/status-instagram-reel \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"reelPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
{
  "reelPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

status-instagram-story

Returns the current posting status of an Instagram story.

Provide the storyPostUuid that was returned by the schedule-instagram-story procedure. The response includes a status field:

  • scheduled — the story is queued and will be posted shortly.
  • executed — the story has been posted to Instagram.
  • failed — posting failed. The errorMessage field contains details.
  • canceled — the story post was canceled before it was posted.

Call this procedure repeatedly to poll until the status is executed or failed.

Preview: Rendering starts right after scheduling. As soon as it has finished (usually within a minute), the response contains a previewUrl: a JPEG of the rendered story with background, text and stickers (the full-size image for image stories, a 360x640 first frame for video stories). Poll until it is present and check the design while the status is still scheduled. If a sticker looks wrong, cancel the story with cancel-instagram-story and schedule it again with the corrected HTML.

How long a story stays scheduled: After schedule-instagram-story returns, the story is rendered and then posted to Instagram, starting at the scheduled date (or immediately when no date was given). The time from scheduled to executed therefore varies with rendering time and Instagram's availability — typically it is under a couple of minutes, but there is no fixed duration, so keep polling instead of assuming a failure after a short delay. The hard upper bound is 60 minutes: a story that could not be posted within 60 minutes after its scheduled time is never posted late, it is marked as failed instead.

curl -X POST https://ORG_UUID.storrito.com/api/v1/status-instagram-story \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"storyPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
{
  "storyPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

status-social-post

Returns the current posting status of a social post.

Provide the socialPostUuid that was passed to schedule-social-post. The response includes a status field:

  • scheduled — the post's date has not come yet.
  • in-progress — the post is due: its media is still rendering, or it is being uploaded and published. A post without a date is due right away. A due post also stays in-progress while the Storrito account has no positive credit balance.
  • executed — the platform published the post. permalink links to it, when the platform reports one.
  • failed — posting failed. The errorMessage field contains details.
  • canceled — the post was canceled before it was published.

Call this procedure repeatedly to poll until the status is executed or failed, or let Storrito notify you with the social_post.status_changed webhook instead (see Webhooks).

curl -X POST https://ORG_UUID.storrito.com/api/v1/status-social-post \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"socialPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
{
  "socialPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

status-tiktok-post

Returns the current posting status of a TikTok post.

Provide the tiktokPostUuid that was returned by the schedule-tiktok-post procedure. The response includes a status field:

  • scheduled — the post is queued or its media is still rendering.
  • in-progress — the post is due and being processed.
  • executed — TikTok confirmed that publishing completed.
  • failed — posting failed. The errorMessage field contains details.
  • canceled — the TikTok post was canceled before it was posted.

Call this procedure repeatedly to poll until the status is executed or failed.

curl -X POST https://ORG_UUID.storrito.com/api/v1/status-tiktok-post \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tiktokPostUuid": "3bda1520-e453-4307-a47c-16e6f4070704"}'
{
  "tiktokPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
}

upload-temp-blob

Uploads a temporary media blob inline as base64 (image, video or audio, max 30 MB decoded).

Use this only when your environment cannot PUT to the presigned URL of create-temp-blob-upload-url — for example a sandboxed AI agent whose network egress does not allow the storage host. The media passes through the API request itself, so prefer the presigned upload whenever possible, especially for videos.

curl -X POST https://ORG_UUID.storrito.com/api/v1/upload-temp-blob \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tempBlobUuid": "3bda1520-e453-4307-a47c-16e6f4070704", "contentType": "image/jpeg", "contentBase64": "'$(base64 -w0 photo.jpg)'"}'

Afterwards use the stable url from the result as the src inside the html of schedule-instagram-story, schedule-instagram-reel, schedule-tiktok-post or schedule-social-post, and to preview the media in a browser.

{
  "tempBlobUuid" : "5f0a97b2-4c31-4f5e-9b6d-2a8c0e7d1f43",
  "contentType" : "image/jpeg",
  "contentBase64" : "/9j/4AAQSkZJRgABAQ..."
}