Simplified
Create. Schedule. Automate
- Category
- Marketing
- Primary Subcategory
- Content Marketing Operations
Integration details
Description
Simplified brings your marketing workspace into ChatGPT. Generate AI images and video, create speech from text, draft and publish social posts across 13 connected channels, manage brand kits, projects and tasks, plan content calendars and campaigns, and analyze social performance — all without leaving the conversation.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Content Marketing Operations
- Secondary Subcategories
- None listed
- Brand
- Simplified
- Access
- Account required
- First tracked
- 2026-07-21
- Tool count
- 115
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Simplified
Get updates when Simplified’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Content Marketing Operations
View Category115 tools agents can invoke
Create a persistent workspace asset. Pass exactly one of: - `url` — a remote file URL the server downloads, OR - `path` — a local file path; the toolkit uploads it via a signed URL and registers the asset (only works when running `smp` / `smp serve` locally — a remote MCP host can't read your filesystem). Processing is async (S3 upload + thumbnail generation via Celery). The returned asset UUID is usable immediately — e.g. in `createProjectItem` `data.assets[]` — but poll `getAsset` until `status=4` (DONE) before relying on the stored URLs. Common use: persist a transient AI-generated image (from `generateImage`) so it can be saved to a project, published, or opened in the editor.
api_createAsset
Retrieve a workspace asset by UUID. Use this to resolve the final stored URLs and to check processing status after an async create (`createAsset` from a URL, or a signed upload) — the asset UUID is returned immediately but the file download / S3 upload / thumbnail generation completes in the background. Key response fields: - `status` — processing state: `0` NOT_STARTED, `1` IN_PROGRESS, `2` PROCESSING_FAILED, `3` THUMBNAIL_FAILED, `4` DONE, `10` NOT_PROCESSED. Poll until `4` before relying on the URLs. - `file_url` / `thumbnail` — signed URLs to the stored file (expire, ~12h; re-fetch to refresh). - `asset_url` — non-signed stored URL. - `asset_type` — image / video / audio / pdf / etc. - `payload` — extracted media metadata (width, height, duration, format, ...). **Path Parameters:** - **id**: Asset UUID (e.g. the id returned by `createAsset`).
api_getAsset
Register an asset after the client successfully PUTs its bytes to the signed storage URL returned by `signAssetUpload`. Carry every registration field from that response unchanged and use the original filename for `asset_name`. Returns the permanent asset UUID used by social `media`.
api_registerAsset
Start the same direct-to-storage upload flow used by Simplified's UI. The client creates a UUID, calls this tool, then PUTs the local file bytes directly to the returned `signed` URL using the declared MIME type and no Simplified Authorization header. After the PUT succeeds, call `registerAsset` with the returned metadata.
api_signAssetUpload
Create a new brand kit in the workspace. Only `title` is required — this makes an empty V2 kit. Populate it afterwards with `buildBrandKit` (canonical brand/style document) and/or context documents (`createContextDocument`). Typical onboarding flow: 1. `createBrandKit` with the brand name as `title` → returns the kit `id` (UUID) 2. `buildBrandKit` with the canonical BrandKitDocument to fill brand + style 3. `getBrandKit?expand=extra` to read it back
api_createBrandKit
Retrieve a brand kit by ID. Default response is `{id, title}` only. Use `?expand=extra` to include the full brand envelope (`brand`, `social_links`, `style`). Use `?expand=website` for the resolved company website URL. Combine with `?expand=extra,website`. Sparse fieldsets via `?fields=` and `?omit=` are honored on the top-level keys. **Path Parameters:** - **brand_id**: Brand kit UUID
api_getBrandKit
List all brand kits in the current workspace. Returns brand kit UUIDs and titles needed for `getBrandKit`, `buildBrandKit`, and the context-document operations. Use `?search=<title>` to filter by name when the user refers to a kit by title. Paginated — pass `page_size` to widen results.
api_listBrandKits
Submit a canonical BrandKitDocument body to populate a brand kit. The body has four top-level sections — all optional, allowing incremental calls: - `brand` — name, description, website URL - `social_links` — array of {type, url} objects - `content_pillars` — 1–5 grounded themes, merged by normalized name - `style` — full visual-identity JSON (colors, typography, logos, imagery, logo_lockup, on_image_copy, ai_guardrails, prose, inferred_fields) The body shape is identical to the GET response (without `id`). Empty body `{}` is a valid no-op. Server-controlled fields (`id`, `version`) in the body are ignored. Runs synchronously and returns 200 with the result. Calling this endpoint multiple times is safe — sections sent overwrite their own fields; omitted sections are left unchanged. Content pillars omitted from a supplied list are preserved. **Do NOT call `getTaskResult` after this** — there is no async task; the operation is complete by the time the response returns. **Path Parameters:** - **brand_id**: Brand kit UUID
api_buildBrandKit
Add a comment to a commentable resource. Set `object_pk` to the resource UUID and `content_type` to the resource family (currently `task`). For threaded replies, set `parent` to the parent comment ID.
api_addComment
Fetch all top-level comments for a commentable resource. Filter by `object_pk` (resource UUID) and `content_type` (resource family, e.g. `task`).
api_listComments
Create a new context document and link it to the brand kit. **Two creation modes:** 1. **Link existing:** Provide `document_id` to link an existing KnowledgeDoc. 2. **Inline creation:** Provide `doc_type` and `name` (plus optional `description`, `data`, `content`) to create a new KnowledgeDoc and link it automatically. **Singleton constraint:** For predefined types (brand_voice, icps, usps, etc.), only one document per type per brandkit is allowed. Attempting to create a duplicate will return a 400 error. The `canonical_key` is auto-set from `doc_type` if it matches a predefined type. **Path Parameters:** - **brand_id**: Brand kit UUID
api_createContextDocument
Delete the link between a brand kit and a context document. If the underlying KnowledgeDoc is not linked to any other brandkit, it is automatically deleted (orphan cleanup). **Path Parameters:** - **brand_id**: Brand kit UUID - **document_link_id**: Either the context-document link UUID (BrandKitContextDocument ID) OR the underlying KnowledgeDoc UUID — the endpoint resolves both.
api_deleteContextDocument
Retrieve one linked context document, including its full content. The `document_link_id` may be EITHER the junction (BrandKitContextDocument) UUID returned by `listContextDocuments`, OR the underlying KnowledgeDoc UUID — the server resolves either form. Use this when you already have a document ID and want its content. To find a document by its canonical type (e.g. `brand_voice`) instead, use `getContextDocumentByType`. To list all documents on a kit, use `listContextDocuments`. **Path Parameters:** - **brand_id**: Brand kit UUID - **document_link_id**: Either the context-document link UUID (BrandKitContextDocument ID) OR the underlying KnowledgeDoc UUID — the endpoint resolves both.
api_getContextDocument
Retrieve a single context document by its canonical type key. Most types return the full KnowledgeDoc directly (not the junction wrapper). For `content_pillars`, the backend reads the Brand Kit's existing structured ContentPillar records, renders cached Markdown on demand, and returns `{doc_type: "content_pillars", content: "..."}`. It does not create or synchronize a KnowledgeDoc. If no structured pillars exist, the endpoint returns 404 even when a legacy active context document exists. **Path Parameters:** - **brand_id**: Brand kit UUID - **context_type**: Canonical type key to retrieve
api_getContextDocumentByType
List all context documents linked to a brand kit. Supports filtering by `canonical_key`, searching by document name or type, and ordering by created/modified timestamps. **Path Parameters:** - **brand_id**: Brand kit UUID
api_listContextDocuments
Update the content of a linked context document. Changes are applied to the underlying KnowledgeDoc, and its version is automatically incremented. **Path Parameters:** - **brand_id**: Brand kit UUID - **document_link_id**: Either the context-document link UUID (BrandKitContextDocument ID) OR the underlying KnowledgeDoc UUID — the endpoint resolves both.
api_updateContextDocument
Create a new long-form document rendered in the Quill editor. Content is stored as Quill Delta JSON (ops array). Used by AI-writer skills (Essay Writer, Article Writer) to persist generated markdown content into an editable document. The returned document is immediately openable at `/ai-writer/document/{space_or_organization}/{id}` in the Simplified web app. To convert markdown content into the required Quill Delta shape, call `markdown_to_quill_delta` from the writers toolkit before passing to this endpoint.
api_createDocument
Returns how many Simplified **credits** the current workspace has left. Credits are the shared currency spent by AI actions — image generation, video generation, and other AI tools all draw down the same balance. Call this tool when: - the user asks about their credits / balance / quota / "how much is left"; - **before** an AI generation, to confirm there's enough balance and avoid a mid-run failure; - **after** a generation fails with an out-of-credits / quota error, to report the remaining balance back to the user. No inputs. The response is a `credits` object: - `credits.remaining` — credits still available to spend - `credits.used` — credits consumed in the current period - `credits.total` — total credits allotted for the period - `credits.trial` — extra trial allowance (only present when on trial)
api_getCreditBalance
Assign or reassign an AI agent (Chatbot) to a project item. The agent will be responsible for processing or executing the item. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID - **id**: Item ID (UUID)
api_assignAgentToItem
Create a new item within the project. The accepted fields vary by resourcetype — inspect a GET response to see available fields for the target type. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID
api_createProjectItem
Retrieve a single project item by its ID. Returns the full item object including status, assignees, and metadata. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID - **id**: Item ID (UUID)
api_getProjectItem
List all items within a project. Items represent individual tasks, content pieces, or entries within the parent project. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID
api_listProjectItems
Move a ProjectItem to a new position within the project. Updates the ordering of items accordingly. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID - **id**: Item ID (UUID)
api_reorderProjectItem
Soft-delete a single item within a project — sets `is_deleted=true`. The item stops appearing in `listProjectItems`/`getProjectItem` but is not purged, so it is recoverable server-side. Requires the parent project ID and matching `resourcetype`. To remove the whole project, use `deleteProject`. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID - **id**: Item ID (UUID)
api_deleteProjectItem
Partially update a project item as a campaign deliverable moves from planned through generation, review, scheduling, and publication. When changing `data`, first read the item and send the complete merged data. **Path Parameters:** - **resourcetype**: Project type selector - **parent_lookup_project_id**: Parent project ID - **id**: Item ID (UUID)
api_updateProjectItem
Sends a single notification. It is routed through the notification registry, which determines delivery channels (in-app, websocket, email, Slack) based on the category.
notify_sendAgentNotification
Create a project of the given `resourcetype`. `title` is the common field; type-specific fields go under `data` (varies by resourcetype — inspect a `getProject` response for the target type to see its shape). Returns the new project's UUID, used for `createProjectItem`, `listProjectItems`, etc. **Path Parameters:** - **resourcetype**: Project type selector (the model name). The API is polymorphic — the same URL structure serves different project types based on this value. Valid values: - `Project` — generic projects (the default for most content). - `AdCreativeProject` — ad-creative projects (specialized fields). Use the same value on create, get, list, and delete for a given project.
api_createProject
Export specified ProjectItems to a partner integration (e.g. WordPress, social media). Provide the partner account ID and the list of item UUIDs to export. **Path Parameters:** - **resourcetype**: Project type selector - **id**: Project ID
api_exportProjectItems
Retrieve a single project by its ID. Returns the full project object with all fields for the given resourcetype. **Path Parameters:** - **resourcetype**: Project type selector - **id**: Project ID (UUID or integer depending on type)
api_getProject
List projects of the given `resourcetype` in the workspace, paginated and newest-first. Returns project objects with their UUIDs — needed for `getProject`, `listProjectItems`, and `deleteProject`. Filter with `?search=<title>`. Pass the same `resourcetype` you created the projects with. **Path Parameters:** - **resourcetype**: Project type selector (the model name). The API is polymorphic — the same URL structure serves different project types based on this value. Valid values: - `Project` — generic projects (the default for most content). - `AdCreativeProject` — ad-creative projects (specialized fields). Use the same value on create, get, list, and delete for a given project.
api_listProjects
Soft-delete a project — sets `is_deleted=true`. The project and its items stop appearing in `listProjects`/`getProject` but are not purged from the database, so this is recoverable server-side. `resourcetype` must match the project's type (`Project` or `AdCreativeProject`) — the same value used to create it. **Path Parameters:** - **resourcetype**: Project type selector - **id**: Project ID (UUID or integer depending on type)
api_deleteProject
Partially update a project. Use this to persist campaign lifecycle, configuration, research, approvals, and rolling outlook state. When changing `data`, first read the project and send the complete merged data object so unrelated state is retained. **Path Parameters:** - **resourcetype**: Project type selector - **id**: Project ID (UUID or integer depending on type)
api_updateProject
Retrieve the status and result of an async task by its `task_id`. Status values: PENDING, STARTED, SUCCESS, FAILURE, RETRY, REVOKED. Note: for most async tools (`generateImage`, media/* operations) the toolkit middleware **already polls this for you** and returns the final result — you rarely need to call it directly. Use it manually only when a long job (e.g. video generation) exceeds the auto-poll window and you got a `task_id` back. **Path Parameters:** - **task_id**: Celery task ID
api_getTaskResult
Fetch a single workspace (organization) by its integer ID — name, plan, settings, and metadata. The API token is bound to one workspace; pass that workspace's ID here to read its details. **Path Parameters:** - **id**: Workspace/Organization ID
api_getWorkspace
Returns the authenticated caller's workspace context in a single call — no workspace ID required. Everything is derived from the auth token or `Organization` header. Response includes: - `user` — id, first_name, last_name, email of the requesting user - `workspace` — id, name, slug, is_active, and settings (timezone, language, start_of_week) - `teamspaces` — active spaces visible in workspace context (id, name, slug, is_active) Do not use this response as the membership authority for `space_id`. Call `listTeamspaces` to resolve IDs the current user can scope into.
api_getWorkspaceInfo
List the teamspaces (Spaces) the current user is a member of, within the token's workspace. Use this to resolve a teamspace before scoping other calls: each returned `id` (integer) is the value you pass as the `Space` header (or `--space` / `space_id`) to narrow a request to that teamspace. The token stays bound to its one workspace — this does not switch workspaces, it only lists the sub-spaces you can scope into. Supports `?search=<name>` to filter by teamspace name and `?expand=settings`. Each item: `{id (int), name, slug}`.
api_listTeamspaces
Append additional drafts to a review bundle previously created via `createSocialMediaReviewBundle`, without recreating it. The operation is idempotent — a draft already present in the bundle is silently skipped, not duplicated. Draft IDs come from `getSocialMediaDrafts`. Returns the updated bundle, including the full list of drafts and the shareable review URL.
social_addDraftsToSocialMediaReviewBundle
Create a review bundle, optionally seeding it with drafts. A review bundle groups social media drafts under a single shareable review URL so collaborators or clients can approve content before it is scheduled or published. Pass `draft_ids` to seed the bundle on creation, or create an empty bundle and append drafts later via `addDraftsToSocialMediaReviewBundle`. Draft IDs come from `getSocialMediaDrafts`. The response includes a `linkToReview` URL to share with reviewers.
social_createSocialMediaReviewBundle
Step 1 — discover the dynamic per-(model, capability) parameter schema before calling `generateVideo`. Not needed for `generateImage`, which takes one fixed contract for every model. A single unified endpoint serves both image and video engines, selected by the required `type` query param. Response modes (driven by which query params you pass): - `type` only → `{models: [...]}` — list every registered engine of that type, its capabilities, and metadata (incl. `credits_per_image` / `estimated_time`). Use this to pick a `model_id`. - `type` + `model_id` → single-model detail with capabilities map. - `type` + `model_id` + `capability` → the full FieldDescriptor schema for that (model, capability) pair (labels, field_type, required flags, enum_values, defaults). This is the contract that `generateImage` / `generateVideo`'s `parameters` must match. Use this before generating — it eliminates 400 errors on invalid / missing parameter keys.
api_getModelFields
Generate an AI image from a prompt, optionally guided by reference images. One call: POST `{model, parameters}` (`capability` is optional). It **blocks and returns the final result** — do not call `getTaskResult`. Use the field names below as-is for every model; the server adapts the payload to the model you chose. If something does not fit that model (a ratio it lacks, too many references for the mode), the error says exactly what to change. `storage` controls where the result is kept: - "asset" — saved to your asset library for reuse (recommended) - "transient" — temporary, not saved - "default" — kept in the image gallery
api_generateImage
Generate an AI video from a prompt, an image, two frames, several images, or a source video. One call: POST `{model, parameters}` (`capability` is optional — derived from which inputs you send). It **blocks and returns the final result** — do not poll. Use the input slot names below as-is for every model; the server adapts the payload to the model you chose. If something does not fit that model (a ratio, duration or resolution it lacks, too many images for the mode), the error says exactly what to change. `getModelFields` (`type=video`) is optional — call it only when you want the model's duration/resolution options before choosing. ## Why `task_id` is misleading here The endpoint also returns a `task_id`, but it tracks the *submission* Celery task that hands the request off to FAL/Kie — it flips to SUCCESS almost immediately, well before the actual video is rendered. **Do not call `getTaskResult` on this `task_id`** — it tells you nothing useful about generation completion. Always poll `getVideoVariation` instead. The apikit middleware strips `task_id` from this response automatically to avoid confusion. ## Storage modes - `default` — persists into the AiImageArt gallery (recommended). - `transient` — generated without surfacing in the gallery; useful for one-shot agent runs. - `asset` — saves the rendered video as a standalone reusable `TldrAsset` (no gallery entry).
api_generateVideo
Convert text to spoken audio using the voice referenced by `voice_id` (get voices from `listVoices`). `storage` controls whether the audio is saved. Set `use_ssml: true` ONLY when `text` contains SSML markup like `<speak>` / `<break>` / `<emphasis>`. For plain prose leave it false — providers handle punctuation pacing well and SSML support varies. Storage modes: - `default` — returns the audio URL only (can expire) - `asset` — also saves it to your asset library for reuse **Path Parameters:** - **voice_id**: Voice UUID from listVoices `voices[].id`
api_generateAudio
Retrieve a single voice by its UUID. Use this to resolve a bare `voice_id` — one the user picked in a voice picker, or a saved preference — back to its attributes without re-listing the whole catalog: `gender` (0=Male, 1=Female, 3=Neutral), `voice_name`, `is_premium`, `description`, and `supports_instructions` (whether the voice honors the `instructions` hint on generateAudio). The response is a single voice object — the same shape as one entry of `listVoices`'s `voices[]`. Resolution is workspace-scoped: a voice owned by another workspace (and not globally published) returns 404. **Path Parameters:** - **voice_id**: Voice UUID (the `id` from a `listVoices` `voices[]` entry).
api_getVoice
List voices available to the current workspace, filtered by language. `language_code` is the ONLY required parameter — use an exact BCP-47 locale (`en-US`, `en-GB`, `fr-FR`, `hi-IN`, `ja-JP`). Combine with `is_premium=true` for a short, high-quality shortlist. The optional filters (`gender`, `provider`, `engine`, `is_premium`, `language_name`, `search`) all default to an empty string `""`, which means "no filter — return everything". Leave them at `""` unless the user explicitly asked to filter. Do NOT substitute `0`/`false` for "no filter": `0` is a REAL value (gender 0 = Male, provider 0 = Google, engine 0 = Neural), so sending it silently narrows the list. The empty-string default is the ONLY correct "unset" value. Response: - `voices[]`: `id` (uuid), `voice_name`, `language_code`, `avatar`, `voice_sample`, `gender` (0=Male, 1=Female, 3=Neutral), `is_premium`, `description`, `supports_instructions` (bool — `true` if the voice honors the `instructions` style/pace hint on generateAudio). Use `id` as `voice_id` in generateAudio. To re-resolve a single known `voice_id` (e.g. from a saved preference) without re-listing, use `getVoice`. - `languages[]`: distinct `{language_code, language_name}` pairs. To resolve a known `voice_name` (e.g. from an avatar roster) to its `id`, pass `voice_name` + `language_code` — that pair is unique, and the `id` differs per locale, so the name must be re-resolved whenever the language changes. Always check the entry you use actually has that `voice_name` rather than trusting `voices[0]` — see the `voice_name` parameter.
api_listVoices
Step 3 — poll this endpoint after `generateVideo`. Read `job_status`: - **Non-terminal**: `CREATED`, `PENDING`, `PROCESSING`, `RENDERING`, `UPDATED` — keep polling. 10s is a reasonable interval. - **Terminal**: `DONE` (success — `payload.output` and `asset_references` are now populated with the rendered video URL) or `FAILED` (error — inspect `payload.errors`). Generation is webhook-driven (FAL / Kie call back into djapp when rendering finishes), so the row updates asynchronously — there is no `task_id` to short-circuit polling. **Path Parameters:** - **art_id**: AiImageArt UUID returned as `id` from `generateVideo`. - **variation_id**: AIArtVariation UUID returned as `art_variation_id` from `generateVideo`.
api_getVideoVariation
Detects the subject and blurs the background. Synchronous — returns image_url directly.
media_blurBackground
Convert an image from one container format to another (jpg, jpeg, png, webp, gif, bmp, tiff). Pass the source `image_url` and the target `output_format`. This changes the file format ONLY — for pixel-level edits (background removal, upscale, inpaint) use the other image tools in this module. Async — returns a task_id (auto-polled).
media_convertImageFormat
Fill a masked region of an image with AI-generated content described by `prompt`. Requires a mask (`mask_url` or `mask_base64`) marking WHERE to fill. Use this when you have a specific region to replace; for removing an object by description (no mask) use `magicInpaint`; to extend the image past its edges use `imageOutpainting`. Async — returns a task_id (auto-polled).
media_generativeFill
Remove or replace objects in an image, guided by `prompt`, with no mask needed (the model locates the target). Use for "remove the person" / "replace the car with a bike". With an explicit mask region use `generativeFill`; to extend beyond the borders use `imageOutpainting`. Async — returns a task_id (auto-polled).
media_magicInpaint
Extend an image BEYOND its original borders (uncrop), generating new surrounding content from `prompt`. Requires `mask_url` marking the new area. Different from `generativeFill` (fills a region inside the image) and `magicInpaint` (edits existing content). Async — returns a task_id (auto-polled).
media_imageOutpainting
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Simplified alternatives on ChatGPT?
As of 2026-09-28, Simplified competes with DropTrack, Hook Layer, inblog, Markty, Sequel.io, StoryChief, TopicLift Editorial Copilot, VybeOS, webfaCeMEdia, Weekloop in ChatGPT Content Marketing Operations, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.