{
  "catalogVersion" : 1,
  "baseUrlTemplate" : "https://ORG_UUID.storrito.com/api/v1/",
  "documentationUrl" : "https://storrito.com/documentation/api/v1/index.md",
  "procedures" : [ {
    "name" : "cancel-instagram-reel",
    "doc" : "Cancels a scheduled Instagram reel before it is posted.\n\nProvide the `reelPostUuid` that was returned by the `schedule-instagram-reel` procedure.\n\n- If the reel is still **scheduled**, it will be canceled and the response status will be `canceled`.\n- If the reel was **already canceled**, the response status will be `canceled` (idempotent).\n- If posting **already started**, **succeeded**, or **failed**, an error is returned because the reel cannot be canceled anymore.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-instagram-reel \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"reelPostUuid\": \"EXAMPLE_REEL_POST_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "reelPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID that identifies a scheduled Instagram reel."
        }
      },
      "required" : [ "reelPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "reelPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "reelPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this reel."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "canceled" ],
          "description" : "The status after the cancel attempt: \"canceled\" when successfully canceled or already canceled."
        }
      },
      "required" : [ "reelPostUuid", "status" ]
    },
    "exampleOutput" : {
      "reelPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "canceled"
    }
  }, {
    "name" : "cancel-instagram-story",
    "doc" : "Cancels a scheduled Instagram story post before it is posted.\n\nProvide the `storyPostUuid` that was returned by the `schedule-instagram-story` procedure.\n\n- If the story is still **scheduled**, it will be canceled and the response status will be `canceled`.\n- If the story was **already canceled**, the response status will be `canceled` (idempotent).\n- If the story was **already executed** or **failed**, an error is returned because it cannot be canceled.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-instagram-story \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"storyPostUuid\": \"EXAMPLE_STORY_POST_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "storyPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID returned by `schedule-instagram-story`. Identifies which story post to cancel."
        }
      },
      "required" : [ "storyPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "storyPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "storyPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this story post."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "canceled", "executed", "failed" ],
          "description" : "The status after the cancel attempt: \"canceled\" (successfully canceled or already canceled), \"executed\" (already posted, cannot cancel), or \"failed\" (already posted but failed, cannot cancel)."
        }
      },
      "required" : [ "storyPostUuid", "status" ]
    },
    "exampleOutput" : {
      "storyPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "canceled"
    }
  }, {
    "name" : "cancel-tiktok-post",
    "doc" : "Cancels a scheduled TikTok post before it is posted.\n\nProvide the `tiktokPostUuid` that was returned by the `schedule-tiktok-post` procedure.\n\n- If the post is still **scheduled** or **in progress**, it will be canceled and the response status will be `canceled`.\n- If the post was **already canceled**, the response status will be `canceled` (idempotent).\n- If the post was **already executed** or **failed**, an error is returned because it cannot be canceled.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/cancel-tiktok-post \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tiktokPostUuid\": \"EXAMPLE_TIKTOK_POST_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "tiktokPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID that identifies a TikTok post."
        }
      },
      "required" : [ "tiktokPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "tiktokPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "tiktokPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this TikTok post."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "canceled" ],
          "description" : "The status after the cancel attempt: \"canceled\" when successfully canceled or already canceled."
        }
      },
      "required" : [ "tiktokPostUuid", "status" ]
    },
    "exampleOutput" : {
      "tiktokPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "canceled"
    }
  }, {
    "name" : "create-connect-link",
    "doc" : "Creates a connect-link: a shareable URL that lets an Instagram account owner connect their account to your Storrito workspace in the browser.\n\nShare the returned `connectLinkUrl` with the person who owns the Instagram account (for example your customer). They open it, enter their Instagram credentials on the Storrito connect page, and complete any Instagram verification steps there. Their credentials never pass through your integration.\n\nOnce the account is connected it appears in `list-instagram-users` and can be used with `schedule-instagram-story`.\n\nAn organization can have at most 100 connect-links. Delete unused links in the Storrito app.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/create-connect-link \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"connectLinkUuid\": \"EXAMPLE_CONNECT_LINK_UUID\", \"description\": \"Customer: ACME Corp\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "connectLinkUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this connect-link. Ensures idempotency — creating a connect-link with the same UUID again returns the same URL instead of creating a duplicate. Use `generate-uuid` to create one."
        },
        "description" : {
          "type" : "string",
          "maxLength" : 500,
          "description" : "Optional note about who this link is for (e.g. the customer name). Shown in the connect-link list in the Storrito app. Maximum 500 characters."
        }
      },
      "required" : [ "connectLinkUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "connectLinkUuid" : "4b52922a-3341-4580-adc2-edb475d712c2",
      "description" : "Vl7CQEx0cm1Nf96l15MwV761on8u3670FJzFb6PflYFsqb4LLxKvnp4M79vywviK0y179Z92TQ9u51C4v9YgWMQ7Z2BJuT498rY51bbTt7Tv8tBS7fdMu5rN5Rzji72HB6ghP3647feWl4592MUDwQS"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "connectLinkUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this connect-link."
        },
        "connectLinkUrl" : {
          "type" : "string",
          "description" : "The shareable connect URL. The Instagram account owner opens it in a browser and connects their account to this Storrito workspace. No Storrito login is required — the URL itself is the authorization, so share it only with the intended person."
        }
      },
      "required" : [ "connectLinkUuid", "connectLinkUrl" ]
    },
    "exampleOutput" : {
      "connectLinkUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "connectLinkUrl" : "mWGpAJgu7SdK77XqbGR52q8FEX6r91"
    }
  }, {
    "name" : "create-draft",
    "doc" : "Renders a page built with `<insta-story>` web components and puts it into the Storrito gallery as a draft, without scheduling it.\n\n   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.\n\n   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.\n\n   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.\n\n   Unknown JSON keys are rejected. This prevents typos from being silently ignored.\n\n   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.\n\n   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.\n\n   **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.\n\n   **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.\n\n   **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`.\n\n   **Quota:** A maximum of 100 drafts can be created in any rolling 24-hour window. Deleted drafts count as well.\n\n   **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`.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/create-draft \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\n       \"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>\",\n       \"draftUuid\": \"EXAMPLE_DRAFT_UUID\",\n       \"name\": \"Travel promo\",\n       \"folderName\": \"API drafts\"\n     }'\n   ```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "url" : {
          "type" : "string",
          "description" : "The URL of your page built with <insta-story> web components. The server will load this URL, render the design, and extract any sticker metadata. Provide either `url` or `html`, but not both."
        },
        "html" : {
          "type" : "string",
          "maxLength" : 10485760,
          "description" : "Inline HTML string containing your <insta-story> web components. The server injects the component JS and fonts automatically — just provide the HTML. Provide either `url` or `html`, but not both. Maximum 10 MB. Media uploaded via `create-temp-blob-upload-url` can be referenced by its temp-blob `url` in src attributes."
        },
        "draftUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this draft. Ensures idempotency — if a draft with this UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests. Use `generate-uuid` to create one."
        },
        "name" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 200,
          "description" : "Optional name of the draft, shown in the Storrito gallery so that the reviewer can tell drafts apart. Defaults to \"api-story\". Maximum 200 characters."
        },
        "folderName" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 512,
          "description" : "Optional name of a top-level gallery folder to put the draft into, for example \"API drafts\". The folder is created when it does not exist yet. When omitted the draft is put on the top-level of the gallery."
        }
      },
      "required" : [ "draftUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "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" : "EXAMPLE_DRAFT_UUID",
      "name" : "Travel promo",
      "folderName" : "API drafts"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "draftUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this draft. Pass it to `status-draft` to poll for the rendered preview, or to `delete-draft` to delete the draft."
        },
        "editorUrl" : {
          "type" : "string",
          "description" : "URL that opens the draft in the Storrito editor. Share it with the person who reviews the draft; it requires a login to the Storrito workspace."
        },
        "warnings" : {
          "type" : "array",
          "items" : {
            "type" : "string"
          },
          "description" : "Only present when the HTML contained unknown `<insta-*>` elements or unknown attributes on sticker elements (they were ignored), or when two stickers overlap on the canvas. The draft was created anyway. Check every warning: if it names something you meant to use or a layout you did not intend, delete the draft with `delete-draft` and create it again with the corrected HTML."
        }
      },
      "required" : [ "draftUuid", "editorUrl" ]
    },
    "exampleOutput" : {
      "draftUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "editorUrl" : "mWGpAJgu7SdK77XqbGR52q8FEX6r91",
      "warnings" : [ "9u21pO9PGXutn1uyr5i", "7ZgTGOQ4trbm0v0jmZ0TaO9fC1a", "S", "qVh4clHvC7DeFdw1", "lLNL4NN97o5J9O9H5NVD", "z73q75tZeZ923", "4A4PK5Yqq6u2c400BGv72inv1b9ut1", "xIktpNM", "wkoiYQbByQI7k7HPnpkW7v9w5dd" ]
    }
  }, {
    "name" : "create-temp-blob-upload-url",
    "doc" : "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:\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/create-temp-blob-upload-url \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tempBlobUuid\": \"EXAMPLE_TEMP_BLOB_UUID\", \"contentType\": \"video/mp4\", \"contentLengthBytes\": '$(stat -c%s story.mp4)'}'\n\ncurl -T story.mp4 -H \"Content-Type: video/mp4\" \"UPLOAD_URL\"\n```\n\nAfterwards use the stable `url` from the result as the src inside the `html` of `schedule-instagram-story`, `schedule-instagram-reel` or `schedule-tiktok-post`, and to preview the media in a browser (a GET redirects to a short-lived download URL), for example:\n\n```\n<insta-story><img src=\"TEMP_BLOB_URL\"></insta-story>\n```\n\nTemp-blobs are deleted automatically about a day after the upload — schedule the post within 24 hours.",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "tempBlobUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this temp-blob. Temp-blobs are immutable — when one with this UUID already exists, the result carries no `uploadUrl` since there is nothing to upload. Use `generate-uuid` to create one."
        },
        "contentType" : {
          "type" : "string",
          "description" : "The media type of the file, e.g. \"image/jpeg\" or \"video/mp4\". Only image/*, video/* and audio/* are accepted. The upload must send exactly this Content-Type header."
        },
        "contentLengthBytes" : {
          "type" : "integer",
          "minimum" : 1,
          "maximum" : 104857600,
          "description" : "The exact size of the file in bytes (max 100 MB). The upload must send exactly this Content-Length, which curl does automatically for `-T file`."
        }
      },
      "required" : [ "tempBlobUuid", "contentType", "contentLengthBytes" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "tempBlobUuid" : "5f0a97b2-4c31-4f5e-9b6d-2a8c0e7d1f43",
      "contentType" : "video/mp4",
      "contentLengthBytes" : 8388608
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "tempBlobUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this temp-blob."
        },
        "url" : {
          "type" : "string",
          "description" : "The stable URL of the temp-blob. After the upload, use it as the src inside the `html` of other procedures and in preview HTML — a GET responds with a 302 redirect to a short-lived download URL. Works until the temp-blob is deleted automatically, about a day after the upload."
        },
        "uploadUrl" : {
          "type" : "string",
          "description" : "PUT the file to this URL within 15 minutes, with the announced Content-Type header. Sandboxed environments with restricted network egress must allow the URL's storage host — when that is not possible, upload via `upload-temp-blob` instead. Absent when the temp-blob already exists — temp-blobs are immutable, so there is nothing to upload."
        }
      },
      "required" : [ "tempBlobUuid", "url" ]
    },
    "exampleOutput" : {
      "tempBlobUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "url" : "mWGpAJgu7SdK77XqbGR52q8FEX6r91",
      "uploadUrl" : "Vl7CQEx0k"
    }
  }, {
    "name" : "delete-draft",
    "doc" : "Deletes a draft that was created by `create-draft`. The draft disappears from the Storrito gallery.\n\nProvide the `draftUuid` that was passed to `create-draft`.\n\n- If the draft still exists, it is deleted and the response status is `deleted`.\n- If the draft was **already deleted**, the response status is `deleted` as well (idempotent).\n- If a user has already **scheduled or posted** the draft, an error is returned. Cancel the post in the Storrito app first.\n\nWhen a user edited the draft in the Storrito editor, the latest saved version is deleted.\n\nUse 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.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/delete-draft \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"draftUuid\": \"EXAMPLE_DRAFT_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "draftUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that was passed to `create-draft`. Identifies which draft to delete."
        }
      },
      "required" : [ "draftUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "draftUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "draftUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this draft."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "deleted" ],
          "description" : "Always \"deleted\": the draft was deleted or had already been deleted."
        }
      },
      "required" : [ "draftUuid", "status" ]
    },
    "exampleOutput" : {
      "draftUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "deleted"
    }
  }, {
    "name" : "generate-uuid",
    "doc" : "Generates a random UUID. Useful for creating a `storyPostUuid` before calling `schedule-instagram-story` or a `tiktokPostUuid` before calling `schedule-tiktok-post`.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/generate-uuid \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{}'\n   ```",
    "inputSchema" : {
      "type" : "object",
      "properties" : { },
      "additionalProperties" : false
    },
    "exampleInput" : { },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "uuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A randomly generated UUID."
        }
      },
      "required" : [ "uuid" ]
    },
    "exampleOutput" : {
      "uuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    }
  }, {
    "name" : "list-instagram-users",
    "doc" : "Lists all Instagram users connected to your Storrito account.\n\n   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.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/list-instagram-users \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{}'\n   ```",
    "inputSchema" : {
      "type" : "object",
      "properties" : { },
      "additionalProperties" : false
    },
    "exampleInput" : { },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "instagramUsers" : {
          "type" : "array",
          "items" : {
            "type" : "object",
            "properties" : {
              "instagramId" : {
                "type" : "string",
                "pattern" : "^\\d{1,50}$",
                "example" : "5940467223",
                "title" : "Instagram ID",
                "description" : "The ID used by Instagram for a entity like an user"
              },
              "instagramUsername" : {
                "type" : "string",
                "minLength" : 1,
                "maxLength" : 64,
                "example" : "maxx80000",
                "title" : "Instagram username",
                "description" : "An Instagram username"
              },
              "facebookDestinations" : {
                "type" : "array",
                "items" : {
                  "type" : "object",
                  "properties" : {
                    "facebookDestinationId" : {
                      "type" : "string",
                      "minLength" : 1,
                      "maxLength" : 64,
                      "description" : "Facebook destination ID to pass to `schedule-instagram-story` as `facebookDestinationId`."
                    },
                    "facebookDestinationName" : {
                      "type" : "string",
                      "minLength" : 1,
                      "maxLength" : 200,
                      "description" : "Human-readable Facebook page or profile name."
                    },
                    "facebookDestinationType" : {
                      "type" : "string",
                      "minLength" : 1,
                      "maxLength" : 64,
                      "description" : "Facebook destination type passed to Instagram when cross-posting."
                    }
                  },
                  "required" : [ "facebookDestinationId", "facebookDestinationName", "facebookDestinationType" ]
                }
              }
            },
            "required" : [ "instagramId", "instagramUsername" ]
          }
        }
      },
      "required" : [ "instagramUsers" ]
    },
    "exampleOutput" : {
      "instagramUsers" : [ {
        "instagramId" : "9",
        "instagramUsername" : "6xkaMjn1026d",
        "facebookDestinations" : [ {
          "facebookDestinationId" : "iyuveZri2TC152g1nVjsmJYz79PTPP42L5D3PBzcZsI60",
          "facebookDestinationName" : "F23sAiwJHpvdI86p6LJ01f0cD6Q6JzBJ8CMrJFEYN0uvDvP2teE93kkLXbxCKsAyo6t0j8PV66R5UDZbU83vbmG6Bk8Z7qrf4Z1TYl0g24y0bFdQ6mIzdEZ1awKqyk5Yd8D27f2cW43OVSIQ7Z484XLKCsnBV23HLw4aC9V1lu1WIm65Z90kQsZ26t4E3P14ZwBa",
          "facebookDestinationType" : "Ie88bay2Uj3A11CmjHO"
        }, {
          "facebookDestinationId" : "k5qu4mOv0n5OiMV883R4nwtLxM",
          "facebookDestinationName" : "623q04u8RZ6j81ciRzUSMIVWV4L7QdU8GF7864qR1EczdrOAJoy47fc1Qe115zCnn7PlSgHN4f19LWFD98ZGr8tyDown76eJI4o4lc8BAE4441E9fi1a17BY20Rxtg5g9yMck6Jp86davX2rgBcAD5o5U32UTd",
          "facebookDestinationType" : "E8grzwISIdYt5xXzA51Q9K3RxHFv6Tdxq262999glyS2ck86VAVA2B4m"
        }, {
          "facebookDestinationId" : "2mj910326ssXOuYW85tOy8hDoE5hWIMPpOAVBq1E66UezB",
          "facebookDestinationName" : "KGzeAy2GNoNQLrz2kM4796HX006c8wB7U54HGoBk10gG5Q1iCO6yQ95vHQ2jq9avQ3Nitw0KqoW349bc4809l14H3J6uM3Ih4zZRCFeBRkX1Coud1q0WLNj8V914C2woH5I70L3DU5MuzLj0AyRAbWKU5J7EzcB3roEoHe",
          "facebookDestinationType" : "4a5MiyIavT18z2"
        }, {
          "facebookDestinationId" : "u598gQ2w7Rg9I4I509oxdfsQk3P",
          "facebookDestinationName" : "BkU4HIrpw561BYemkj3C3g2831rLmHol07BUp7p6F9PdSy3lHE21X371wKiAl53200GAB47H9gwoObWCM3d0DpHMJx",
          "facebookDestinationType" : "4r292TOjHDT2HGro14Zd"
        }, {
          "facebookDestinationId" : "z2NKq23c0WHXQ90AzdzSw8q96TAlK54dQi2",
          "facebookDestinationName" : "LIK6O7t52L2u7H7Eu41ql36dRluNG7N0w4XrKiD08HGoKo1GB",
          "facebookDestinationType" : "L2jYJBQKIHPnAr5F13780"
        }, {
          "facebookDestinationId" : "0Owa9n034g85K9yX10O2BjUnKSU9TV0vD4Yy98S5",
          "facebookDestinationName" : "453Stn6p56XBTtEE360oD6v6O8e75n4UuX4YXc92q07qwFrl8nR7PTHk8EfLS4D22CLN1kE9OtJ2sAfLwnXPx830S07x4YoORbhl3zNd",
          "facebookDestinationType" : "BTK6UsIl3Ed995993p27sORVbagfHgAYFYlVjZ555FL7U69g1516tHpa3GXq"
        }, {
          "facebookDestinationId" : "9d5qL4eX84w74Nn5825pHBCIjR41WAHQ1p5kp6m07gt49Cm8E3cPi2881gB8",
          "facebookDestinationName" : "28e43s5aI20OxWgZs2149urLwa5cKm3CyZmG2WJEF9J98d55E448O76dJ3k315EbqrQS4y66ViKGtd44ohjWo9Mkp1po35x0FWUbAi2TUO44EDu52Fxba5le35SXTP6jA54dJP66uU1T3X5F4R7Pmn0f6Ps0C0xB",
          "facebookDestinationType" : "yNbBLt0HjSqDhLYA83a3KA3a92wDj4O9lk"
        }, {
          "facebookDestinationId" : "3c9",
          "facebookDestinationName" : "cENsA3qLVahtK",
          "facebookDestinationType" : "a30hMrJ84X6i04W38ec5CgtSjmyM7ug390KT5e"
        }, {
          "facebookDestinationId" : "6LC26rNOyeI6zf0wT9hTPzX16BepGM2qDuxG0K9HbopO6299",
          "facebookDestinationName" : "tCUp3uh2lE4kxqc0GAx4q0351Ai21jN43266AafY7eMZX65j3tYC20o2TFypaFe0QVtun5d87s3S6a2Fy",
          "facebookDestinationType" : "79Y7yQF7VaYptwIa49pogkhWlMHIb5"
        }, {
          "facebookDestinationId" : "D9lZGZxLK69XRt9u",
          "facebookDestinationName" : "sK3z0653Ok6ebHHAYrtr2nh1CM5KUFvAXr",
          "facebookDestinationType" : "aOS"
        }, {
          "facebookDestinationId" : "QAwMzNyp69Y7Wo9xktT5lwrQ1OZnYv718x1ztb0254lZDKu9inO9V6",
          "facebookDestinationName" : "ZYD4Hm9W3A5c",
          "facebookDestinationType" : "P6G144cXVWcq84838ZdBR2coc0"
        }, {
          "facebookDestinationId" : "4139N114ynBDJ0r3U206d23Shz3mg7PTGAlTV",
          "facebookDestinationName" : "OZFrabTrLBBzOsnqGTBJ2tUW70uc5A055XFD54np2TbhE0ZZ7JTpvxR95mqgCWl6L5MlmHsu0f18W24UFQg6OvIaZ482kbg8z9h82017uR5Yw1UIBGk0il3ch65FQ5PI3Z1vN1V95r5E1Ip2hwnDM38D2YI050eIslf5agR07dA48aSW0I",
          "facebookDestinationType" : "msDu"
        }, {
          "facebookDestinationId" : "x3wW3a4tnC2IAl8Wg1r4aMLmC9YXc1dddIKXJ9",
          "facebookDestinationName" : "xM4n2VRa",
          "facebookDestinationType" : "6492RT6gm1636w38o1kcqC8rrFK7w24M1aD3N"
        }, {
          "facebookDestinationId" : "KNcec0S564cKEjU7r20Bs2g2149H8Os9Nd0Pi3LR04xZN1L6ckpRI86DFRRqLzR2",
          "facebookDestinationName" : "442KSm8TW1btaFu8oDu61T4LEa8Mbx9X911t7K4tVXIKOevowN7hcSt1uaW9415d0jmv3s303H16hZdx1Ihye6Eyairm71SQ2z6KHZfCUr78fVEwFi32S2V596x0nwz5Zf406",
          "facebookDestinationType" : "ep"
        }, {
          "facebookDestinationId" : "gkC5U2Z8Re7Vi9KB",
          "facebookDestinationName" : "3b9JC2k7RC4MJJg1I3U9l47aT5En4QgOD526I20aV263X5JbIFS1UF31UfRBH3V9o80SgVGIg17E2K2249WkchOj7hjNmc89le1dIHjF2rf1eCuI2LrdcfQ6v3UdSTIqM2Cy63jnStDoaW7X882",
          "facebookDestinationType" : "9oX818Ru0FobK5xpn3uCnq2kUZ4n843nZFMla"
        } ]
      }, {
        "instagramId" : "4610931507493614809578541613973232763570",
        "instagramUsername" : "MYibtyzlQfiLV2nzl6"
      }, {
        "instagramId" : "663301239676142561",
        "instagramUsername" : "xFz074xuY"
      } ]
    }
  }, {
    "name" : "list-tiktok-accounts",
    "doc" : "Lists all TikTok accounts connected to your Storrito account.\n\n   Returns an array of TikTok accounts with their display name and account ID. Use the `tiktokAccountId` value when calling `schedule-tiktok-post`.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/list-tiktok-accounts \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{}'\n   ```",
    "inputSchema" : {
      "type" : "object",
      "properties" : { },
      "additionalProperties" : false
    },
    "exampleInput" : { },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "tiktokAccounts" : {
          "type" : "array",
          "items" : {
            "type" : "object",
            "properties" : {
              "tiktokAccountId" : {
                "type" : "string",
                "minLength" : 1,
                "maxLength" : 128,
                "example" : "_000sIZJZmZpNRkCm4luQprxgrTgklr4a_ru",
                "title" : "TikTok account ID",
                "description" : "The TikTok open_id of a connected TikTok account. Use `list-tiktok-accounts` to find it."
              },
              "tiktokAccountName" : {
                "type" : "string",
                "minLength" : 1,
                "maxLength" : 100,
                "example" : "storrito03",
                "title" : "TikTok account name",
                "description" : "The display name of a connected TikTok account."
              },
              "profilePictureUrl" : {
                "type" : "string",
                "description" : "Profile picture URL of the connected TikTok account."
              }
            },
            "required" : [ "tiktokAccountId", "tiktokAccountName" ]
          }
        }
      },
      "required" : [ "tiktokAccounts" ]
    },
    "exampleOutput" : {
      "tiktokAccounts" : [ {
        "tiktokAccountId" : "9ahLj6i048eHko84tv",
        "tiktokAccountName" : "B9LYUIjhzTrI69dEjra8AlPFfn8V6vF5v0jAE7mxMrOz2516JB4O8ipTOE9uqvhh1d7058rQRSZz26s6pxNJd87t1D",
        "profilePictureUrl" : "1fW"
      } ]
    }
  }, {
    "name" : "schedule-instagram-reel",
    "doc" : "Renders a page built with `<insta-story>` web components and schedules the rendered video as an Instagram reel.\n\n   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.\n\n   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.\n\n   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.\n\n   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.\n\n   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.\n\n   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.\n\n   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.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-instagram-reel \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\n       \"html\": \"<insta-story src=\\\"https://example.com/my-reel.mp4\\\"></insta-story>\",\n       \"instagramUsername\": \"YOUR_INSTAGRAM_USERNAME\",\n       \"reelPostUuid\": \"EXAMPLE_REEL_POST_UUID\",\n       \"caption\": \"My first reel via the Storrito API\"\n     }'\n   ```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "caption" : {
          "type" : "string",
          "maxLength" : 2200,
          "description" : "Optional Instagram caption for the reel. Maximum 2200 characters."
        },
        "date" : {
          "type" : "string",
          "description" : "An optional ISO 8601 date-time string (e.g. \"2025-06-15T14:30:00Z\") to schedule the reel for a future time. When omitted the reel is published as soon as rendering is complete."
        },
        "reelPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this reel. Ensures idempotency — if a reel with this UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests without risk of posting the same reel twice."
        },
        "instagramUsername" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 64,
          "example" : "maxx80000",
          "title" : "Instagram username",
          "description" : "An Instagram username"
        },
        "shareToFeed" : {
          "type" : "boolean",
          "description" : "When true, the reel is also shared to the account's main feed. Defaults to false."
        },
        "aiGenerated" : {
          "type" : "boolean",
          "description" : "Mark the reel as AI-generated content, so Instagram shows its AI label on the reel."
        },
        "shareToFacebook" : {
          "type" : "boolean",
          "description" : "When true, the reel is recommended on Facebook. Defaults to true."
        },
        "url" : {
          "type" : "string",
          "description" : "The URL of your page built with <insta-story> web components. The server will load this URL, render the reel video, and schedule it as an Instagram reel. Provide either `url` or `html`, but not both."
        },
        "html" : {
          "type" : "string",
          "maxLength" : 10485760,
          "description" : "Inline HTML string containing your <insta-story> web components. The server injects the component JS and fonts automatically — just provide the HTML. Provide either `url` or `html`, but not both. Maximum 10 MB. Media uploaded via `create-temp-blob-upload-url` can be referenced by its temp-blob `url` in src attributes."
        }
      },
      "required" : [ "instagramUsername", "reelPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "html" : "<insta-story src=\"https://example.com/my-reel.mp4\"></insta-story>",
      "instagramUsername" : "YOUR_INSTAGRAM_USERNAME",
      "reelPostUuid" : "EXAMPLE_REEL_POST_UUID",
      "caption" : "My first reel via the Storrito API"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "reelPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this reel. Pass it to the `status-instagram-reel` procedure to poll for the posting status."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "scheduled" ],
          "description" : "Always \"scheduled\" for a newly created or already existing reel. Use `status-instagram-reel` to poll for the final status."
        }
      },
      "required" : [ "reelPostUuid", "status" ]
    },
    "exampleOutput" : {
      "reelPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "scheduled"
    }
  }, {
    "name" : "schedule-instagram-story",
    "doc" : "Renders a page built with `<insta-story>` web components and schedules it as an Instagram story.\n\n   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.\n\n   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.\n\n   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.\n\n   Optionally set `aiGenerated` to `true` to mark the story as AI-generated content, so Instagram shows its AI label on the story.\n\n   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.\n\n   Unknown JSON keys are rejected. This prevents typos from being silently ignored.\n\n   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.\n\n   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.\n\n   **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.\n\n   **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.\n\n   **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`.\n\n   **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.\n\n   **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.\n\n   **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.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-instagram-story \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\n       \"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>\",\n       \"instagramUsername\": \"YOUR_INSTAGRAM_USERNAME\",\n       \"storyPostUuid\": \"EXAMPLE_STORY_POST_UUID\"\n     }'\n   ```\n\n**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).\n\n- `<insta-story>`: attributes `src`. Example: `<insta-story src=\"https://assets.mixkit.co/videos/1164/1164-1080.mp4\"></insta-story>`\n- `<insta-hashtag>`: attributes `hashtag`, `design` (default/gray/rainbow). Example: `<insta-hashtag hashtag=\"summer\" design=\"gray\"></insta-hashtag>`\n- `<insta-mention>`: attributes `username`, `design` (default/gray/rainbow). Example: `<insta-mention username=\"johndoe\" design=\"gray\"></insta-mention>`\n- `<insta-location>`: attributes `location`, `location-id`, `design` (default/gray/black/orange/rainbow). Example: `<insta-location location=\"Berlin\" design=\"gray\"></insta-location>`\n- `<insta-link>`: attributes `url`, `text`, `design` (default/gray/black/rainbow). Example: `<insta-link url=\"https://example.com\" text=\"Shop Now\" design=\"gray\"></insta-link>`\n- `<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>`\n- `<insta-question>`: attributes `question`, `color` (white/black/pink/lavender/purple/orange/green/blue). Example: `<insta-question question=\"Ask me anything!\" color=\"white\"></insta-question>`\n- `<insta-quiz>`: attributes `question`, `options`, `correct-answer`. Example: `<insta-quiz question=\"Capital of France?\" options='[\"London\", \"Paris\", \"Berlin\", \"Madrid\"]' correct-answer=\"1\"></insta-quiz>`\n- `<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>`\n- `<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>`\n\nThe 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).",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "url" : {
          "type" : "string",
          "description" : "The URL of your page built with <insta-story> web components. The server will load this URL, render the story, and extract any sticker metadata. Provide either `url` or `html`, but not both."
        },
        "html" : {
          "type" : "string",
          "maxLength" : 10485760,
          "description" : "Inline HTML string containing your <insta-story> web components. The server injects the component JS and fonts automatically — just provide the HTML. Provide either `url` or `html`, but not both. Maximum 10 MB. Media uploaded via `create-temp-blob-upload-url` can be referenced by its temp-blob `url` in src attributes."
        },
        "instagramUsername" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 64,
          "example" : "maxx80000",
          "title" : "Instagram username",
          "description" : "An Instagram username"
        },
        "storyPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this story post. Ensures idempotency — if a story post with this UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests without risk of posting the same story twice."
        },
        "date" : {
          "type" : "string",
          "description" : "An optional ISO 8601 date-time string (e.g. \"2025-06-15T14:30:00Z\") to schedule the story for a future time. When omitted the story is posted immediately."
        },
        "aiGenerated" : {
          "type" : "boolean",
          "description" : "Mark the story as AI-generated content, so Instagram shows its AI label on the story."
        },
        "shareToFacebook" : {
          "type" : "boolean",
          "description" : "When true, cross-posts the Story to a Facebook destination linked to the Instagram account. If `facebookDestinationId` is omitted, Storrito uses the first linked Facebook destination for that Instagram account."
        },
        "facebookDestinationId" : {
          "anyOf" : [ {
            "type" : "string"
          }, {
            "type" : "integer"
          } ],
          "description" : "Optional Facebook destination ID to use when `shareToFacebook` is true. The destination must be linked to the selected Instagram account."
        }
      },
      "required" : [ "instagramUsername", "storyPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "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" : "EXAMPLE_STORY_POST_UUID"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "storyPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this story post. Pass it to the `status-instagram-story` procedure to poll for the posting status."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "scheduled" ],
          "description" : "Always \"scheduled\" for a newly created or scheduled story. Use `status-instagram-story` to poll for the final status."
        },
        "warnings" : {
          "type" : "array",
          "items" : {
            "type" : "string"
          },
          "description" : "Only present when the HTML contained unknown `<insta-*>` elements or unknown attributes on sticker elements (they were ignored), or when two stickers overlap on the canvas. The story was scheduled anyway. Check every warning: if it 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."
        }
      },
      "required" : [ "storyPostUuid", "status" ]
    },
    "exampleOutput" : {
      "storyPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "scheduled",
      "warnings" : [ "9u21pO9PGXutn1uyr5i", "7ZgTGOQ4trbm0v0jmZ0TaO9fC1a", "S", "qVh4clHvC7DeFdw1", "lLNL4NN97o5J9O9H5NVD", "z73q75tZeZ923", "4A4PK5Yqq6u2c400BGv72inv1b9ut1", "xIktpNM", "wkoiYQbByQI7k7HPnpkW7v9w5dd" ]
    }
  }, {
    "name" : "schedule-tiktok-post",
    "doc" : "Renders a page built with `<insta-story>` web components and schedules the rendered media as a TikTok post.\n\n   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.\n\n   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.\n\n   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.\n\n   For rendered image/photo posts, TikTok allows `title` to be at most 90 characters. Put longer text into `description`.\n\n   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.\n\n   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.\n\n   Use `list-tiktok-accounts` to find the `tiktokAccountId` of a connected account.\n\n   ```\n   curl -X POST https://ORG_UUID.storrito.com/api/v1/schedule-tiktok-post \\\n     -H \"Authorization: Bearer $TOKEN\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\n       \"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>\",\n       \"tiktokAccountId\": \"YOUR_TIKTOK_ACCOUNT_ID\",\n       \"tiktokPostUuid\": \"EXAMPLE_TIKTOK_POST_UUID\"\n     }'\n   ```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "description" : {
          "type" : "string",
          "maxLength" : 2200,
          "description" : "Optional TikTok description."
        },
        "date" : {
          "type" : "string",
          "description" : "An optional ISO 8601 date-time string (e.g. \"2025-06-15T14:30:00Z\") to schedule the TikTok post for a future time. When omitted the post is published as soon as rendering is complete."
        },
        "tiktokPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this TikTok post. Ensures idempotency — if a TikTok post with this UUID already exists, the same success response is returned without creating a duplicate. This makes it safe to retry requests without risk of posting the same TikTok twice."
        },
        "videoCoverTimestampMs" : {
          "type" : "integer",
          "minimum" : 0,
          "description" : "Video frame timestamp in milliseconds used as the TikTok cover. TikTok uses the first frame when omitted or invalid."
        },
        "disableDuet" : {
          "type" : "boolean",
          "description" : "Disable duets for the TikTok post."
        },
        "brandOrganic" : {
          "type" : "boolean",
          "description" : "Enable TikTok's brand organic disclosure toggle."
        },
        "disableComment" : {
          "type" : "boolean",
          "description" : "Disable comments for the TikTok post."
        },
        "brandedContent" : {
          "type" : "boolean",
          "description" : "Enable TikTok's branded content disclosure toggle."
        },
        "privacyLevel" : {
          "type" : "string",
          "enum" : [ "PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "FOLLOWER_OF_CREATOR", "SELF_ONLY" ],
          "description" : "TikTok privacy level. Defaults to SELF_ONLY."
        },
        "title" : {
          "type" : "string",
          "maxLength" : 2200,
          "description" : "Optional TikTok title/caption. TikTok photo posts allow at most 90 characters; video captions can be longer."
        },
        "aiGenerated" : {
          "type" : "boolean",
          "description" : "Mark the post as AI-generated content."
        },
        "autoAudio" : {
          "type" : "boolean",
          "description" : "Let TikTok automatically add audio to photo posts."
        },
        "tiktokAccountId" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 128,
          "example" : "_000sIZJZmZpNRkCm4luQprxgrTgklr4a_ru",
          "title" : "TikTok account ID",
          "description" : "The TikTok open_id of a connected TikTok account. Use `list-tiktok-accounts` to find it."
        },
        "url" : {
          "type" : "string",
          "description" : "The URL of your page built with <insta-story> web components. The server will load this URL, render the story, and schedule the rendered media as a TikTok post. Provide either `url` or `html`, but not both."
        },
        "disableStitch" : {
          "type" : "boolean",
          "description" : "Disable stitches for the TikTok post."
        },
        "html" : {
          "type" : "string",
          "maxLength" : 10485760,
          "description" : "Inline HTML string containing your <insta-story> web components. The server injects the component JS and fonts automatically — just provide the HTML. Provide either `url` or `html`, but not both. Maximum 10 MB. Media uploaded via `create-temp-blob-upload-url` can be referenced by its temp-blob `url` in src attributes."
        }
      },
      "required" : [ "tiktokAccountId", "tiktokPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "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" : "EXAMPLE_TIKTOK_POST_UUID"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "tiktokPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this TikTok post. Pass it to the `status-tiktok-post` procedure to poll for the posting status."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "scheduled" ],
          "description" : "Always \"scheduled\" for a newly created or already existing TikTok post. Use `status-tiktok-post` to poll for the final status."
        }
      },
      "required" : [ "tiktokPostUuid", "status" ]
    },
    "exampleOutput" : {
      "tiktokPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "scheduled"
    }
  }, {
    "name" : "status-draft",
    "doc" : "Returns the current status of a draft that was created by `create-draft`.\n\nProvide the `draftUuid` that was passed to `create-draft`. The response includes a `status` field:\n\n- `rendering` — the draft is in the gallery, its preview is not rendered yet.\n- `ready` — the draft is rendered. The `previewUrl` field contains a JPEG of the rendered design.\n- `failed` — the rendering failed for good. Delete the draft with `delete-draft` and create it again.\n- `deleted` — the draft was deleted, in the Storrito app or via `delete-draft`.\n\nRendering 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.\n\nWhen a user edits the draft in the Storrito editor, this procedure follows the edit: status, `previewUrl` and `editorUrl` describe the latest saved version.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/status-draft \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"draftUuid\": \"EXAMPLE_DRAFT_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "draftUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that was passed to `create-draft`. Identifies which draft to check."
        }
      },
      "required" : [ "draftUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "draftUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "draftUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this draft."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "rendering", "ready", "failed", "deleted" ],
          "description" : "The current status: \"rendering\" (the preview is not ready yet), \"ready\" (rendered, see previewUrl), \"failed\" (the rendering failed for good) or \"deleted\" (deleted in the Storrito app or via `delete-draft`)."
        },
        "previewUrl" : {
          "type" : "string",
          "description" : "URL of a JPEG of the rendered draft (background, text and stickers): the full-size image for image designs, a 360x640 first frame for video designs. Present as soon as the rendering has finished, usually within a minute after `create-draft`."
        },
        "editorUrl" : {
          "type" : "string",
          "description" : "URL that opens the draft in the Storrito editor. It requires a login to the Storrito workspace. Not present when the draft is deleted."
        }
      },
      "required" : [ "draftUuid", "status" ]
    },
    "exampleOutput" : {
      "draftUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "ready",
      "editorUrl" : "qP"
    }
  }, {
    "name" : "status-instagram-reel",
    "doc" : "Returns the current posting status of an Instagram reel.\n\nProvide the `reelPostUuid` that was returned by the `schedule-instagram-reel` procedure. The response includes a `status` field:\n\n- `scheduled` — the reel is queued or its video is still rendering.\n- `in-progress` — the reel is due and being processed.\n- `executed` — the reel has been posted to Instagram.\n- `failed` — posting failed. The `errorMessage` field contains details.\n- `canceled` — the reel was canceled before it was posted.\n\nCall this procedure repeatedly to poll until the status is `executed` or `failed`.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/status-instagram-reel \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"reelPostUuid\": \"EXAMPLE_REEL_POST_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "reelPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID that identifies a scheduled Instagram reel."
        }
      },
      "required" : [ "reelPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "reelPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "reelPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this reel."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "scheduled", "in-progress", "executed", "failed", "canceled" ],
          "description" : "The current posting status: \"scheduled\" (queued or rendering), \"in-progress\" (due and being processed), \"executed\" (posted to Instagram), \"failed\" (see errorMessage), or \"canceled\"."
        },
        "errorMessage" : {
          "type" : "string",
          "description" : "A human-readable error description. Only present when status is \"failed\"."
        }
      },
      "required" : [ "reelPostUuid", "status" ]
    },
    "exampleOutput" : {
      "reelPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "in-progress",
      "errorMessage" : "Vl7CQEx0k"
    }
  }, {
    "name" : "status-instagram-story",
    "doc" : "Returns the current posting status of an Instagram story.\n\nProvide the `storyPostUuid` that was returned by the `schedule-instagram-story` procedure. The response includes a `status` field:\n\n- `scheduled` — the story is queued and will be posted shortly.\n- `executed` — the story has been posted to Instagram.\n- `failed` — posting failed. The `errorMessage` field contains details.\n- `canceled` — the story post was canceled before it was posted.\n\nCall this procedure repeatedly to poll until the status is `executed` or `failed`.\n\n**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.\n\n**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.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/status-instagram-story \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"storyPostUuid\": \"EXAMPLE_STORY_POST_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "storyPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID returned by `schedule-instagram-story`. Identifies which story post to check."
        }
      },
      "required" : [ "storyPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "storyPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "storyPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this story post."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "scheduled", "executed", "failed", "canceled" ],
          "description" : "The current posting status: \"scheduled\" (queued, will be posted shortly), \"executed\" (posted to Instagram), \"failed\" (see errorMessage), or \"canceled\"."
        },
        "errorMessage" : {
          "type" : "string",
          "description" : "A human-readable error description. Only present when status is \"failed\"."
        },
        "previewUrl" : {
          "type" : "string",
          "description" : "URL of a JPEG of the rendered story (background, text and stickers): the full-size image for image stories, a 360x640 first frame for video stories. Present as soon as the rendering has finished, usually within a minute after scheduling. Open it to verify the design while the status is still \"scheduled\"; if something is off, cancel the story with `cancel-instagram-story` and schedule it again with corrected HTML."
        }
      },
      "required" : [ "storyPostUuid", "status" ]
    },
    "exampleOutput" : {
      "storyPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "executed",
      "previewUrl" : "qP"
    }
  }, {
    "name" : "status-tiktok-post",
    "doc" : "Returns the current posting status of a TikTok post.\n\nProvide the `tiktokPostUuid` that was returned by the `schedule-tiktok-post` procedure. The response includes a `status` field:\n\n- `scheduled` — the post is queued or its media is still rendering.\n- `in-progress` — the post is due and being processed.\n- `executed` — TikTok confirmed that publishing completed.\n- `failed` — posting failed. The `errorMessage` field contains details.\n- `canceled` — the TikTok post was canceled before it was posted.\n\nCall this procedure repeatedly to poll until the status is `executed` or `failed`.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/status-tiktok-post \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tiktokPostUuid\": \"EXAMPLE_TIKTOK_POST_UUID\"}'\n```",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "tiktokPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID that identifies a TikTok post."
        }
      },
      "required" : [ "tiktokPostUuid" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "tiktokPostUuid" : "4b52922a-3341-4580-adc2-edb475d712c2"
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "tiktokPostUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this TikTok post."
        },
        "status" : {
          "type" : "string",
          "enum" : [ "scheduled", "in-progress", "executed", "failed", "canceled" ],
          "description" : "The current posting status: \"scheduled\" (queued or rendering), \"in-progress\" (due and being processed), \"executed\" (accepted by TikTok), \"failed\" (see errorMessage), or \"canceled\"."
        },
        "errorMessage" : {
          "type" : "string",
          "description" : "A human-readable error description. Only present when status is \"failed\"."
        },
        "tiktokStatus" : {
          "type" : "string",
          "description" : "The last raw publish status returned by TikTok, if available."
        }
      },
      "required" : [ "tiktokPostUuid", "status" ]
    },
    "exampleOutput" : {
      "tiktokPostUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "status" : "in-progress",
      "tiktokStatus" : "qP"
    }
  }, {
    "name" : "upload-temp-blob",
    "doc" : "Uploads a temporary media blob inline as base64 (image, video or audio, max 30 MB decoded).\n\nUse 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.\n\n```\ncurl -X POST https://ORG_UUID.storrito.com/api/v1/upload-temp-blob \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"tempBlobUuid\": \"EXAMPLE_TEMP_BLOB_UUID\", \"contentType\": \"image/jpeg\", \"contentBase64\": \"'$(base64 -w0 photo.jpg)'\"}'\n```\n\nAfterwards use the stable `url` from the result as the src inside the `html` of `schedule-instagram-story`, `schedule-instagram-reel` or `schedule-tiktok-post`, and to preview the media in a browser.",
    "inputSchema" : {
      "type" : "object",
      "properties" : {
        "tempBlobUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "A UUID you provide to identify this temp-blob. Temp-blobs are immutable — when one with this UUID already exists, the upload is ignored and the same success response is returned. Use `generate-uuid` to create one."
        },
        "contentBase64" : {
          "type" : "string",
          "maxLength" : 41943040,
          "description" : "The base64-encoded bytes of the image, video or audio file (max 30 MB decoded)."
        },
        "contentType" : {
          "type" : "string",
          "description" : "The media type of the blob, e.g. \"image/jpeg\" or \"video/mp4\". Only image/*, video/* and audio/* are accepted."
        }
      },
      "required" : [ "tempBlobUuid", "contentBase64", "contentType" ],
      "additionalProperties" : false
    },
    "exampleInput" : {
      "tempBlobUuid" : "5f0a97b2-4c31-4f5e-9b6d-2a8c0e7d1f43",
      "contentType" : "image/jpeg",
      "contentBase64" : "/9j/4AAQSkZJRgABAQ..."
    },
    "outputSchema" : {
      "type" : "object",
      "properties" : {
        "tempBlobUuid" : {
          "type" : "string",
          "format" : "uuid",
          "description" : "The UUID that identifies this temp-blob."
        },
        "url" : {
          "type" : "string",
          "description" : "The stable URL of the temp-blob. Use it as the src inside the `html` of other procedures and in preview HTML — a GET responds with a 302 redirect to a short-lived download URL. Works until the temp-blob is deleted automatically, about a day after the upload."
        }
      },
      "required" : [ "tempBlobUuid", "url" ]
    },
    "exampleOutput" : {
      "tempBlobUuid" : "5e0b18ce-66b5-4d62-a452-50b6004b6d01",
      "url" : "mWGpAJgu7SdK77XqbGR52q8FEX6r91"
    }
  } ]
}