Overview

The API generates the same presentations and documents as the Synclo app, from the same credits. Each generated presentation is saved in the API key’s workspace, where it can be edited, shared and presented like any other.

Quick reference

  • Base URL: https://synclo.app/api/v1. Requests and responses are JSON over HTTPS.
  • Authenticate with an API key in the Authorization header: Bearer sy_…. Workspace admins create keys in Settings › API.
  • Generation is asynchronous: POST /generations returns 202 with a generation id; poll GET /generations/{id} every 5 seconds until status is completed or failed.
  • A generation costs 10 credits per slide, the same as in the app. Failed generations aren't charged.
  • Send an Idempotency-Key with POST /generations so a retried request never creates or charges twice.
  • Every response carries a Synclo-Request-Id; include it when you contact support.

The full API is also described in an OpenAPI 3.1 file, openapi.json, for Postman, Insomnia and client generators, and as plain text in developers.md for AI coding tools.

To make presentations from Claude or ChatGPT without code, use the connector. To build your own MCP client, see MCP server and OAuth.

Base URL
https://synclo.app/api/v1

Authentication

Authenticate every request with an API key, sent as a bearer token in the Authorization header. Keys start with sy_.

Workspace admins create and revoke keys in Settings › API. A key belongs to its workspace: generated presentations are saved there, and credits are drawn from its balance. API access is included with Pro, Max and Business; on other plans, requests return 402 plan_required.

A key is shown once, when it’s created. Keep it on your server and never in client-side code. A revoked key stops working immediately and returns 401.

Header
Authorization: Bearer sy_…
Request
curl https://synclo.app/api/v1/me \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "workspace": {
    "id": "5b0e2f71-9c3a-4d8e-b6a1-7e4f0c2d9a63",
    "name": "Acme"
  },
  "plan": {
    "id": "pro",
    "name": "Pro"
  },
  "credits": 1920
}

Quick start

From an API key to a finished presentation.

  1. Create an API key in Settings › API and set it as an environment variable.

    Shell
    export SYNCLO_API_KEY=sy_…
  2. Create a generation, then poll it every 5 seconds until status is completed or failed. Most presentations complete in one to three minutes. The cURL version uses jq.

    Quick start
    ID=$(curl -s https://synclo.app/api/v1/generations \
      -H "Authorization: Bearer $SYNCLO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"input":"A pitch for a neighborhood bike repair shop","slides":8}' | jq -r .id)
    
    while true; do
      GEN=$(curl -s https://synclo.app/api/v1/generations/$ID \
        -H "Authorization: Bearer $SYNCLO_API_KEY")
      STATUS=$(echo "$GEN" | jq -r .status)
      if [ "$STATUS" = completed ] || [ "$STATUS" = failed ]; then break; fi
      sleep 5
    done
    
    echo "$GEN" | jq '.document // .error'
  3. Open document.edit_url to view the presentation in Synclo. Set "share": "link" for a public link, or "export": "pdf" for a file.

Credits

A generation costs the same as in the app: 10 credits per slide, drawn from the workspace’s balance. Images generated with auto are included.

When you create a generation, its estimate (credits.estimated, 10 credits per requested slide) is checked against the balance. If the balance is lower, the request returns 402 insufficient_credits and no generation is created. Credits are reserved when processing starts and charged for the slides generated; failed generations aren’t charged.

Image models other than auto may add credits per image: see Image models. The current balance is returned by GET /me, and a completed generation reports credits.used and credits.remaining. Plans and credit packs are on Pricing.

Response · 402
{
  "error": {
    "code": "insufficient_credits",
    "message": "This generation needs 80 credits; the workspace has 40.",
    "request_id": "req_Q3m8ZkT1vR6yWb2NcX5aLp9Jd4",
    "credits": {
      "balance": 40,
      "needed": 80
    }
  }
}

Create a generation

POST/api/v1/generations

Creates a presentation or document. Returns 202 Accepted with the generation, in the same shape as GET /generations/{id}, and a Location header; processing continues in the background.

Unknown parameters are rejected with 400, so a misspelled parameter is never silently ignored.

Headers

Idempotency-Keyheader

Optional, 1 to 255 characters. A retry with the same key and body within 24 hours returns the original generation with Idempotent-Replayed: true and isn't charged again. See Idempotency.

Body

inputstringRequired

The content to generate from. With generate, a topic or brief; with condense or preserve, the source text, at least 20 words. Up to 400,000 characters; longer input returns 413 too_large.

modestring

How input is used. generate writes new content from a topic or brief. condense summarizes the source text into slides and keeps its facts. preserve keeps the source text as written.

Default: generate

formatstring

slides for a presentation, document for a document of sections.

Default: slides

slidesinteger

The number of slides, the opening slide included (sections, for a document), from 1 to 20. With condense and preserve, the maximum: the source text sets the number, up to this value. Every slide is charged 10 credits.

Default: 8

themestring

The id of a theme from GET /themes. If omitted, Synclo designs a look for the presentation.

Default: A look designed for the presentation

templatestring

The id of a template from GET /templates. The presentation follows the template's structure, and its look unless theme or brand is set.

Default: None

aspectstring

The slide aspect ratio. Applies to slides only.

One of 16:9, 4:3.

Default: 16:9

page_sizestring

fluid pages size to their content; letter and a4 are fixed print sizes. Applies to document only.

Default: fluid

textobject

Text options.

text.amountstring

How much text each slide carries.

One of minimal, concise, detailed, extensive.

Default: Chosen per slide

text.tonestring

The writing style, up to 100 characters, such as warm or formal.

text.audiencestring

The intended audience, up to 200 characters, such as local investors.

text.languagestring

The output language: a BCP 47 tag such as fr or pt-BR, or a language name such as Japanese.

Default: The language of input

imagesobject

Image options.

images.sourcestring

ai generates images. placeholders adds an empty image slot to each slide, to fill in the editor. none adds no images.

Default: ai

images.modelstring

auto, or the id of a model from Image models. With auto, Synclo chooses the model and images are included in the slide price; other models may add credits per image.

Default: auto

images.stylestring

theme uses the theme's image style. Otherwise, the id of a style from Image styles, or a description of up to 500 characters, such as pencil sketches on cream paper.

Default: theme

instructionsstring

Additional instructions for the content and design, up to 2,000 characters, such as Close on the ask.

brandboolean

If true, applies the workspace's brand from Settings › Brand: logo, fonts and colors. Returns 400 if the workspace has no brand.

Default: false

sharestring

link turns on the public link, returned as document.share_url.

One of private, link.

Default: private

exportstring

Generates a file with the presentation: pdf, pptx (PowerPoint), or png (a ZIP with one PNG per slide; a single PNG for a one-slide presentation).

Default: None

Responses

202Generation created
The generation with status queued and credits.estimated. A repeated Idempotency-Key returns the original generation with Idempotent-Replayed: true.
400Invalid request
An invalid or unknown parameter; an unknown theme, template or image model; or "brand": true in a workspace with no brand.
402Insufficient credits
The workspace’s balance is lower than the estimate. No generation is created.
409Idempotency conflict
The Idempotency-Key was already used with a different body.
413Input too large
input exceeds 400,000 characters.
429Too many generations
The workspace already has 2 generations in progress (too_many_running), or the rate limit was reached (rate_limited).
Request
curl -X POST https://synclo.app/api/v1/generations \
  -H "Authorization: Bearer $SYNCLO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c9e1a-2b7d-4c55-9d0e-1a2b3c4d5e6f" \
  -d '{
    "input": "A pitch for a neighborhood bike repair shop",
    "mode": "generate",
    "format": "slides",
    "slides": 8,
    "theme": "cobalt",
    "aspect": "16:9",
    "text": {
      "amount": "concise",
      "tone": "warm",
      "audience": "local investors",
      "language": "en"
    },
    "images": {
      "source": "ai",
      "model": "auto",
      "style": "theme"
    },
    "instructions": "Close on the ask.",
    "brand": false,
    "share": "private",
    "export": "pdf"
  }'
Response · 202
HTTP/1.1 202 Accepted
Location: /api/v1/generations/gen_3f2a9c0e7b1d4e8a9c6f2b5d8e1a4c7b

{
  "id": "gen_3f2a9c0e7b1d4e8a9c6f2b5d8e1a4c7b",
  "object": "generation",
  "status": "queued",
  "created_at": "2026-10-12T14:03:11Z",
  "started_at": null,
  "completed_at": null,
  "document": null,
  "export": null,
  "credits": {
    "estimated": 80,
    "used": null,
    "remaining": null
  },
  "warnings": [],
  "error": null
}

Retrieve a generation

GET/api/v1/generations/{id}

Returns a generation. Poll every 5 seconds until status is completed or failed; most complete in one to three minutes.

Path parameters

idstring

The generation's id, returned by POST /generations.

Response

idstring

Unique identifier: gen_ followed by 32 hexadecimal characters.

objectstring

Always generation.

statusstring

queued, running, completed or failed.

created_atstring

When the generation was created (ISO 8601, UTC).

started_atstring or null

When processing started; null while queued.

completed_atstring or null

When the generation completed or failed; null until then.

documentobject or null

The generated presentation once status is completed; otherwise null.

document.idstring

The document ID, for GET /documents/{id}.

document.titlestring

The title.

document.slidesinteger

The number of slides (or sections), including the opening slide.

document.edit_urlstring

Opens the presentation in the Synclo editor. Requires a workspace member's sign-in.

document.share_urlstring or null

The public link, or null if the link is off.

exportobject or null

The file requested with export, or null. url requires no authentication and expires after 7 days; treat it as a secret. If the file couldn't be generated, the presentation is still created, url is null and error explains why.

export.formatstring

The requested format.

One of pdf, pptx, png.

export.urlstring or null

The download URL.

export.expires_atstring

When url expires.

export.errorstring

Present only if the file couldn't be generated.

creditsobject

Credit usage.

credits.estimatedinteger

10 credits per requested slide, checked against the balance when the generation was created.

credits.usedinteger or null

Credits charged: null until the generation finishes, 0 if it failed.

credits.remaininginteger or null

The workspace's balance after the generation, once completed; otherwise null.

warningsarray of strings

Non-fatal issues: the presentation was created, but a requested option couldn't be applied (for example, the public link couldn't be turned on). Usually empty.

errorobject or null

code and message when status is failed; otherwise null. Failed generations aren't charged. See Errors.

Request
curl https://synclo.app/api/v1/generations/gen_3f2a9c0e7b1d4e8a9c6f2b5d8e1a4c7b \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "id": "gen_3f2a9c0e7b1d4e8a9c6f2b5d8e1a4c7b",
  "object": "generation",
  "status": "completed",
  "created_at": "2026-10-12T14:03:11Z",
  "started_at": "2026-10-12T14:03:12Z",
  "completed_at": "2026-10-12T14:05:02Z",
  "document": {
    "id": "8c1e5b2a-4d3f-4a7e-9b1c-2d6e8f0a3b5c",
    "title": "Spoke & Sprocket",
    "slides": 8,
    "edit_url": "https://synclo.app/d/8c1e5b2a-4d3f-4a7e-9b1c-2d6e8f0a3b5c",
    "share_url": "https://acme.synclo.site/r/spoke-sprocket-x7Kq9TmA2pD"
  },
  "export": {
    "format": "pdf",
    "url": "https://synclo.app/files/kQ7mX2pLw9RaT3vB/spoke-and-sprocket.pdf",
    "expires_at": "2026-10-19T14:05:02Z"
  },
  "credits": {
    "estimated": 80,
    "used": 80,
    "remaining": 1920
  },
  "warnings": [],
  "error": null
}

List themes

GET/api/v1/themes

Returns the themes available for theme: Synclo’s, then the workspace’s own. Workspaces with brand lock return their own themes only.

Response

themes[].idstring

The value to send as theme.

themes[].namestring

The theme's name.

themes[].kindstring

prebuilt for Synclo's themes, workspace for the workspace's own.

themes[].descriptionstring or null

What the theme suits; null for the workspace's own.

Request
curl https://synclo.app/api/v1/themes \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "themes": [
    {
      "id": "cobalt",
      "name": "Cobalt",
      "kind": "prebuilt",
      "description": "Confident business decks"
    },
    {
      "id": "midnight",
      "name": "Midnight",
      "kind": "prebuilt",
      "description": "Launches, tech and evening events"
    },
    …
  ]
}
Synclo themes
idNameDescription
cobaltCobaltConfident business decks
midnightMidnightLaunches, tech and evening events
paprikaPaprikaFood, events and small businesses
recessRecessLessons and classrooms
gridlineGridlineData reports, reviews and research
charterCharterBoards, finance, legal and consulting
billboardBillboardCampaigns, launches and announcements
zurichZurichDesign, architecture and strategy
fernFernHealth, sustainability and nonprofits
bloomBloomPeople, wellbeing and community
galaGalaCelebrations and invitations
folioFolioReports, essays and pre-reads
ledgerLedgerLaw, finance and academia
monoMonoProduct specs and engineering
vowVowWeddings, invitations and hospitality
clayClayCafés, craft and interiors
marigoldMarigoldPosters, youth and community events
inkInkPitch decks and keynotes
graphiteGraphiteProduct reviews and strategy
noirNoirLuxury, fashion and real estate
forestForestNature, wellness and retreats
emberEmberRestaurants, nights out and sports

List templates

GET/api/v1/templates

Returns the templates available for template. A generation from a template follows its structure and look, with content written for your input.

Response

templates[].idstring

The value to send as template.

templates[].namestring

The template's name.

templates[].descriptionstring

What the template makes.

templates[].good_forarray of strings

Typical uses.

Request
curl https://synclo.app/api/v1/templates \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "templates": [
    {
      "id": "waypoint",
      "name": "Lesson",
      "description": "A lesson built as one adventure in one illustrated world: a hook, the skills one stop at a time, a quiz, a partner activity and an exit ticket.",
      "good_for": [
        "Lessons for any age",
        "Classroom activities",
        "Skills workshops for kids"
      ]
    },
    …
  ]
}
Templates
idNameDescription
waypointLessonA lesson built as one adventure in one illustrated world: a hook, the skills one stop at a time, a quiz, a partner activity and an exit ticket.
thresholdPortfolioSelected work told the same way each time: before and after at one seam, the details, what changed and the client's words.
plumblineProposalA client proposal that shows the work as it is and as it will be, the options side by side, the schedule and every line of the price.
transitResearch reportSurvey findings where every chart makes one point and says who was asked, how many and what the question was.
block-partyEvent invitationAn invitation that runs the whole day: when and where, the programme, a map, what to bring, how to help and how to reply.
debutProduct launchA launch told through the product itself: its screens built as real cards, three customers followed through their day.
fanfareMarketing campaignA campaign plan at poster volume: the line, the creative, where it runs, the weeks and the numbers that prove it worked.
mondayWeekly updateA team's week on one strip, Monday to Friday: what got done, what is at risk and the decisions needed.
groundworkProject statusEvery measure read as planned against actual, with today marked wherever time appears and the site photographed month by month.
caliperQuarterly reviewA quarter read like an instrument: every figure against its target and tolerance, red only where it is out.
upswingSeed pitchA raise told along the company's own growth curve: flat on the problem, rising on the proof, dashed into the plan.
proofCase studyA customer story told as measured change: every claim a before and an after.
chromaProduct catalogueA range where every product owns a color: its page, its photograph and its place in the index.
huddleWorkshopA hands-on session in three modules, each with its own shape and color, drawn as warm flat illustration.
show-and-tellSchool projectA bright class project where the subject itself appears on every slide, big enough to read from the back row.
runwayInvestor updateThe quarter told against the runway: every figure read against how long the money lasts.
overcastLessonA lesson that makes a class see it: a hook, a vote, the story in pictures, a check at the end.
throughlineStrategy reportThe answer on the cover, then the case: every title a claim, every slide placed in the argument.
lineupWedding weekendThree days told as a small festival: the line-up, the set times, the stages and the wristband.
endpointResearch talkA study presented figure by figure, each with its takeaway in plain words.
hushClient proposalFrom the problem you can measure to the change you promise, priced and scheduled.
forecastProduct roadmapWhat ships now, what comes next and what is still a chance, with the odds on each.
playbackResearch readoutWhat customers told you, each finding with how many said it.
shadeImpact reportA year of work for donors and partners, measured in what changed.
call-sheetTrip planWho's coming, each day's plan and call time, the bookings and the budget.
wayfindingOnboardingA new hire's first month: the people, the tools, the rituals and the checklist.
pitch-tallySeed pitchThe problem, the traction and the ask, for investors.
report-reviewBusiness reviewA leadership team’s numbers, one point a slide.
lesson-water-cycleLessonA class from the hook to the exit question, with one activity.
proposal-harbor-pineClient proposalThe scope, the approach, the timeline and the price.
themes-talusProduct launchWhat it is, who it’s for and how it sells.
editor-kickoffSales presentationWhat customers get, with the numbers that prove it.
research-heatConference talkResearch turned into a talk, every source kept.
teams-weeklyWeekly updateWhat shipped, what’s next and where the team needs help.
present-bikesYear in reviewA year’s story for a room: what happened, what it cost, what’s next.
pdf-greenlineBoard updateA quarter’s results and decisions, ready for the board.
export-fitoutProject pitchOptions side by side, with the costs and a timeline.
invite-samParty invitationWho, when and where, and the one thing to keep quiet.
doc-riversideGrant applicationThe problem, the plan, the budget and who does what.

Retrieve the workspace

GET/api/v1/me

Returns the API key’s workspace, its plan and its credit balance.

Response

workspace.idstring

The workspace ID.

workspace.namestring or null

The workspace name.

plan.idstring

pro, max, business.

plan.namestring

The plan name.

creditsinteger or null

The workspace's credit balance.

Request
curl https://synclo.app/api/v1/me \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "workspace": {
    "id": "5b0e2f71-9c3a-4d8e-b6a1-7e4f0c2d9a63",
    "name": "Acme"
  },
  "plan": {
    "id": "pro",
    "name": "Pro"
  },
  "credits": 1920
}

List documents

GET/api/v1/documents

Returns the workspace’s documents visible to the key’s owner, most recently updated first, up to 100. Documents in Trash are excluded.

Response

documents[].idstring

The document ID.

documents[].titlestring

The title.

documents[].updated_atstring

When the document was last updated.

documents[].created_atstring

When the document was created.

documents[].share_urlstring or null

The public link, or null if the link is off.

Request
curl https://synclo.app/api/v1/documents \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "documents": [
    {
      "id": "8c1e5b2a-4d3f-4a7e-9b1c-2d6e8f0a3b5c",
      "title": "Spoke & Sprocket",
      "updated_at": "2026-10-12T14:05:02Z",
      "created_at": "2026-10-12T14:03:12Z",
      "share_url": "https://acme.synclo.site/r/spoke-sprocket-x7Kq9TmA2pD"
    }
  ]
}

Retrieve a document

GET/api/v1/documents/{id}

Returns a document with its full content: sections and blocks as Synclo stores them, its theme and its public link. An invalid ID returns 400; a document the key can’t access returns 404.

Path parameters

idstring

The document ID (a UUID), from document.id or GET /documents.

Response

idstring

The document ID.

titlestring

The title.

themestring

The ID of the theme it uses.

updated_atstring

When the document was last updated.

created_atstring

When the document was created.

share_urlstring or null

The public link, or null if the link is off.

documentobject

The content: sections and blocks.

Request
curl https://synclo.app/api/v1/documents/8c1e5b2a-4d3f-4a7e-9b1c-2d6e8f0a3b5c \
  -H "Authorization: Bearer $SYNCLO_API_KEY"
Response · 200
{
  "id": "8c1e5b2a-4d3f-4a7e-9b1c-2d6e8f0a3b5c",
  "title": "Spoke & Sprocket",
  "theme": "cobalt",
  "updated_at": "2026-10-12T14:05:02Z",
  "created_at": "2026-10-12T14:03:12Z",
  "share_url": "https://acme.synclo.site/r/spoke-sprocket-x7Kq9TmA2pD",
  "document": {
    "version": 1,
    "title": "Spoke & Sprocket",
    "sections": [
      …
    ],
    "citations": []
  }
}

MCP server

POSThttps://synclo.app/mcp

The MCP server lets Claude, ChatGPT and other MCP clients create and read presentations for a person who signs in with their Synclo account. It’s the server behind the Claude and ChatGPT connector; this section is for connecting other clients.

Connection

Address
https://synclo.app/mcp
Transport
Streamable HTTP. Send one JSON-RPC 2.0 message per POST; responses are JSON. Notifications return 202 with no body, and GET returns 405.
Protocol versions
2025-11-25, 2025-06-18 and 2025-03-26.
Authorization
An OAuth access token for the person, sent as Authorization: Bearer syo_…. See OAuth.
Plans
Every plan, Free included. A connection acts in one workspace, which the person picks when they allow access.

Generations

Generation is asynchronous, as in the API. create_presentation returns a generation_id at once; get_generation waits up to 40 seconds for the generation before it returns, so call it again until the status is completed or failed. Most presentations complete in one to three minutes.

The same request within 10 minutes returns the first generation instead of starting another, so a retried call isn’t charged twice.

Credits and limits

A generation costs the same as in the API: 10 credits per slide from the connected workspace’s balance. Failed generations aren’t charged. The workspace’s plan sets the most slides per presentation: 10 on Free, 20 on Plus, Pro, Max and Business.

Calls are rate limited per connection, with the same limits as API requests.

Results and errors

A tool returns its result as text content and as structuredContent. A call that can’t complete returns a result with isError: true and a readable message. When the workspace has no credits left, the message is “This workspace is out of credits. Add credits at synclo.app.”

Without a valid access token, the server returns 401 with a WWW-Authenticate header that names the protected resource metadata and the scopes, plus error="invalid_token" when the token sent is expired or revoked, was issued for another resource, or belongs to a person who is no longer a member of the workspace. A tool that needs a scope the token lacks returns 403 insufficient_scope.

Claude Code
claude mcp add --transport http synclo https://synclo.app/mcp
.mcp.json
{
  "mcpServers": {
    "synclo": {
      "type": "http",
      "url": "https://synclo.app/mcp"
    }
  }
}
Request
POST /mcp HTTP/1.1
Host: synclo.app
Authorization: Bearer syo_…
Content-Type: application/json
Accept: application/json, text/event-stream

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "create_presentation",
    "arguments": {
      "input": "A pitch for a neighborhood bike repair shop",
      "slides": 8
    }
  }
}
Response · 401
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://synclo.app/.well-known/oauth-protected-resource/mcp", scope="presentations:read presentations:write"
Tools
ToolTitleScopeDescription
create_presentationCreate a presentationpresentations:writeCreates a designed presentation in Synclo: a pitch deck, a sales or board deck, a lesson, a report, a proposal or any slides, written and designed with pictures and charts, or a document of sections. Works from a topic, a brief, an outline or source text, and saves it in the connected workspace. Returns a generation_id at once; a presentation takes three to five minutes, and in chat apps that show Synclo's card, the card shows it as it is written and when it is ready. Costs 10 credits per slide, the opening slide included. A repeat of the same request within 10 minutes returns the first generation.
get_generationCheck on a presentationpresentations:readReturns a generation's status. Waits up to 40 seconds for it to finish. When completed, returns the presentation's title, slide count, editor link, public link (if on) and the credits used and remaining; when failed, the reason. In chat apps that show Synclo's card, the card under create_presentation already shows the finished presentation.
export_presentationExport a presentationpresentations:readCreates a PDF, PowerPoint (pptx) or PNG file of a presentation in the workspace and returns a download link that works for 7 days. A workspace can make up to 50 files a day through connected apps, one at a time.
search_presentationsFind presentationspresentations:readLists the workspace's presentations and documents the person can see, most recently updated first, optionally filtered by words in the title.
show_presentationShow a presentationpresentations:readShows a presentation from the workspace in the chat, slide by slide, with links to open, present and download it. Returns its title, slide count and editor link. A presentation made with create_presentation in this chat is shown by its own card already.
read_presentationRead a presentationpresentations:readReturns a presentation's text, slide by slide: each slide's title and words.
list_themesList themespresentations:readLists the themes a presentation can use: Synclo's, then the workspace's own.
list_templatesList templatespresentations:readLists the templates a presentation can follow.

create_presentation arguments

inputstringRequired

What to make (a topic or brief), or the source text to turn into slides. Up to 400,000 characters.

modestring

generate writes new content from a topic or a brief; condense makes slides from source text, tightening its words and keeping its facts; preserve keeps every word of the source text as written. Default generate.

One of generate, condense, preserve.

formatstring

slides for a presentation, document for a document of sections. Default slides.

One of slides, document.

slidesinteger

The number of slides in all, the opening slide included: 5 makes the opening and four more. Default 8. From 1 to 20.

themestring

A theme id from list_themes. If omitted, Synclo designs a look for the presentation.

templatestring

A template id from list_templates.

languagestring

The output language, such as fr or Japanese. Default: the language of input. Up to 60 characters.

tonestring

The writing style, such as warm or formal. Up to 100 characters.

audiencestring

The intended audience. Up to 200 characters.

image_stylestring

theme (the default), a style id, or a description of the images. Up to 500 characters.

instructionsstring

Additional instructions for the content and design. Up to 2,000 characters.

Other tools’ arguments
ToolArguments
get_generationgeneration_id (required)
export_presentationdocument_id (required), format (required)
search_presentationsquery, limit
show_presentationdocument_id (required)
read_presentationdocument_id (required)
list_themesNone
list_templatesNone

OAuth

Synclo is an OAuth 2.1 authorization server for the MCP server. Claude, ChatGPT and other MCP clients find it through discovery and need no setup; this section is for building your own client.

Use OAuth when your app acts for people in their own Synclo workspaces, on any plan. Access tokens work on the MCP server only. To automate your own workspace through the REST API, use an API key.

Discovery

GET /.well-known/oauth-protected-resource/mcp
Protected resource metadata (RFC 9728): the resource https://synclo.app/mcp, its authorization server and its scopes. Also served at /.well-known/oauth-protected-resource.
GET /.well-known/oauth-authorization-server
Authorization server metadata (RFC 8414): the endpoints below and what each supports.

Endpoints

GET /oauth/authorize
Shows the person the Allow screen; returns to redirect_uri with a code.
POST /oauth/token
Exchanges a code or a refresh token for tokens. Form-encoded.
POST /oauth/register
Dynamic client registration (RFC 7591), for public clients.
POST /oauth/revoke
Revokes an access or refresh token (RFC 7009). Always returns 200.

Scopes

presentations:write
Create presentations and documents in the workspace. Spends its credits. Tools: create_presentation.
presentations:read
Find, read and show the presentations the person can open in the workspace, download them as files, list themes and templates, and check generations. Tools: get_generation, export_presentation, search_presentations, show_presentation, read_presentation, list_themes, list_templates.

Client registration

Clients are public: there’s no client secret, and the token endpoint’s authentication method is none. Register in either of two ways.

  • Client ID Metadata Document (preferred). Use an https URL as your client_id. It serves JSON with client_id (the same URL), client_name and redirect_uris, and optionally logo_uri and client_uri. It must respond within 5 seconds and be at most 16 KB. Synclo keeps a copy for up to 24 hours, so a change can take a day to apply.
  • Dynamic client registration. POST /oauth/register (RFC 7591) with client_name and redirect_uris; keep the client_id it returns. Registration is rate limited.

Redirect URIs must match exactly. Loopback addresses (http://127.0.0.1 and http://localhost) match on any port, for desktop and command-line clients.

Authorization

Send the person to /oauth/authorize with response_type=code, client_id, redirect_uri, state, a PKCE code_challenge with code_challenge_method=S256 (plain isn’t supported), scope (space-separated; both scopes when omitted) and resource=https://synclo.app/mcp (RFC 8707; optional, and any other value returns invalid_target).

The person signs in if they need to, then sees your app’s name, the address it returns to and the permissions it asks for. They pick one workspace and choose Allow or Cancel. Synclo returns to redirect_uri with code and state, or with error. Every response carries iss=https://synclo.app (RFC 9207): check it before using the code.

A code is valid for 10 minutes and works once, with the same client, redirect URI, verifier and resource.

Tokens

Exchange the code at POST /oauth/token (form-encoded) with grant_type=authorization_code, code, redirect_uri, client_id, code_verifier and resource. The response holds an access token (syo_…) that expires after 1 hour and a refresh token (syr_…).

Refresh with grant_type=refresh_token. Each refresh returns a new refresh token, and the one sent stops working. Sending a refresh token that was already used revokes every token of that connection; the person then connects again. A connection can be refreshed for up to 90 days from the person’s approval, then needs a new authorization.

Errors use the codes of RFC 6749 and RFC 8707: invalid_request, invalid_client, invalid_grant, invalid_target and unsupported_grant_type. The token endpoint is rate limited. Token responses carry Cache-Control: no-store. Keep tokens on your server, never in URLs or logs.

Revocation

POST /oauth/revoke with token (RFC 7009) revokes it and always returns 200. A person can disconnect your app at any time in Settings › Connected apps, and its tokens stop working at once. Every call checks that the person is still a member of the workspace.

Authorization server metadata
{
  "issuer": "https://synclo.app",
  "authorization_endpoint": "https://synclo.app/oauth/authorize",
  "token_endpoint": "https://synclo.app/oauth/token",
  "registration_endpoint": "https://synclo.app/oauth/register",
  "revocation_endpoint": "https://synclo.app/oauth/revoke",
  "response_types_supported": [
    "code"
  ],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token"
  ],
  "code_challenge_methods_supported": [
    "S256"
  ],
  "token_endpoint_auth_methods_supported": [
    "none"
  ],
  "revocation_endpoint_auth_methods_supported": [
    "none"
  ],
  "scopes_supported": [
    "presentations:read",
    "presentations:write"
  ],
  "client_id_metadata_document_supported": true,
  "authorization_response_iss_parameter_supported": true,
  "service_documentation": "https://synclo.app/developers/oauth"
}
Authorization URL
https://synclo.app/oauth/authorize
  ?response_type=code
  &client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient.json
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback
  &scope=presentations%3Aread%20presentations%3Awrite
  &state=af0ifjsldkj
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
  &resource=https%3A%2F%2Fsynclo.app%2Fmcp
Token request
curl -X POST https://synclo.app/oauth/token \
  -d grant_type=authorization_code \
  -d code=$CODE \
  -d redirect_uri=https://app.example.com/oauth/callback \
  -d client_id=https://app.example.com/oauth/client.json \
  -d code_verifier=$CODE_VERIFIER \
  -d resource=https://synclo.app/mcp
Response · 200
{
  "access_token": "syo_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "syr_…",
  "scope": "presentations:read presentations:write"
}
Refresh
curl -X POST https://synclo.app/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token=$REFRESH_TOKEN \
  -d client_id=https://app.example.com/oauth/client.json \
  -d resource=https://synclo.app/mcp
Client ID Metadata Document
{
  "client_id": "https://app.example.com/oauth/client.json",
  "client_name": "Example App",
  "redirect_uris": [
    "https://app.example.com/oauth/callback"
  ],
  "logo_uri": "https://app.example.com/logo.png",
  "client_uri": "https://app.example.com"
}

Image models

Set images.model to a model’s id, or to auto to let Synclo choose per image. Images generated with auto are included in the slide price.

Fast models add no credits. Quality and Specialist models add up to the credits below for each image they generate.

idNameKindAdded credits per image
autoAutoChosen by SyncloNone
seedream-5-flashSeedream 5.0 FlashFastNone
flux-2-fastFlux 2 FastFastNone
nano-banana-2-liteNano Banana 2 LiteFastNone
nano-banana-2.1Nano Banana 2.1QualityUp to 6
gpt-image-2.5-flareGPT Image 2.5 FlareQualityUp to 8
flux-3Flux 3QualityUp to 7
seedream-5-proSeedream 5.0 ProQualityUp to 7
recraft-v4.1Recraft V4.1SpecialistUp to 5
nano-banana-2.1-hdNano Banana 2.1 HDSpecialistUp to 8

Image styles

Set images.style to a style’s id, to theme for the theme’s own style, or to a description of up to 500 characters.

idNameKind
themeThe theme’s styleDefault
photoTrue to lifePhotography
lifestyleBright and candidPhotography
cinematicGolden hourPhotography
black-whiteBlack and whitePhotography
still-lifeProduct close-upPhotography
illustrationFlat vectorIllustration
picture-bookPicture bookIllustration
watercolorWatercolorIllustration
isometricIsometricIllustration
flat-lineLine artHand-drawn
ink-sketchInk sketchHand-drawn
3dSoft 3DMade by hand
paper-cutoutPaper cutMade by hand
feltFeltMade by hand
bold-posterScreen-print posterGraphic
bauhausBauhausGraphic
magazine-cutoutCollageGraphic
neon-glowNeonGraphic
wavesSilk wavesAbstract
liquid-glassLiquid glassAbstract
paint-swirlPaint swirlAbstract

Errors

Errors share one shape: code is stable and meant for your code; message is readable text that may change; request_id matches the response’s Synclo-Request-Id header. Include the request ID when you contact support@synclo.app.

A generation that fails after it starts isn’t an error response: GET /generations/{id} returns 200 with status failed and an error whose code is listed in the second table. Failed generations aren’t charged.

Error response
{
  "error": {
    "code": "invalid_request",
    "message": "…",
    "request_id": "req_…"
  }
}
Error responses
StatuscodeDescription
400invalid_requestThe request body or a parameter is invalid, or a parameter is unknown. message names the parameter.
401unauthorizedThe API key is missing or invalid. The response includes WWW-Authenticate: Bearer realm="synclo".
402insufficient_creditsThe workspace doesn't have enough credits. error.credits includes balance and needed.
402plan_requiredThe workspace's plan doesn't include API access.
403forbiddenThe API key's owner is no longer a member of the workspace. Create a new key in Settings › API.
404not_foundThe generation or document doesn't exist in this workspace.
409idempotency_conflictThe Idempotency-Key was already used with a different request body.
413too_largeinput exceeds 400,000 characters.
429rate_limitedToo many requests. Retry after the number of seconds in Retry-After.
429too_many_runningThe workspace already has 2 generations in progress. Retry when one completes.
500internalAn unexpected error occurred. Retry; if it persists, contact support@synclo.app with the request ID.
503unavailableThe generation couldn't be started. Retry shortly; no credits were charged.
Failed generations
error.codeDescription
insufficient_creditsAnother generation spent the workspace's balance before this one started.
unavailableSynclo was temporarily unavailable. Retry the request.
generation_failedThe presentation couldn't be generated. Retry the request.
forbiddenThe API key's owner is no longer a member of the workspace.
timed_outThe generation ran longer than 15 minutes.
internalAn unexpected error occurred.

Rate limits

Requests are rate limited per workspace, and the limit depends on the plan. Every response reports the current window in these headers:

X-RateLimit-Limitheader

The number of requests allowed in the current window.

X-RateLimit-Remainingheader

The number of requests remaining in the current window.

X-RateLimit-Resetheader

When the current window resets, as a Unix timestamp.

Retry-Afterheader

On 429 responses: the number of seconds to wait before retrying.

Requests over the limit return 429 rate_limited; retry after Retry-After seconds. Polling GET /generations/{id} has a separate, higher limit, so polling every 5 seconds won’t exhaust it. A workspace can run 2 generations at a time; another returns 429 too_many_running.

Response headers
HTTP/1.1 200 OK
Synclo-Request-Id: req_Q3m8ZkT1vR6yWb2NcX5aLp9Jd4
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1791817200

Idempotency

A network error can hide a response after a generation was created. To retry safely, send an Idempotency-Key with POST /generations: a retry with the same key and body within 24 hours returns the original generation, with Idempotent-Replayed: true, and isn’t charged again.

Reusing a key with a different body returns 409 idempotency_conflict. Use a new key, such as a UUID, for each presentation.

Header
Idempotency-Key: 6f1c9e1a-2b7d-4c55-9d0e-1a2b3c4d5e6f

Scope

What the API doesn’t do yet, and what to do instead.

Editing a presentation
The API creates presentations and documents but doesn't edit them. Generate a new one with revised input, or open document.edit_url to change it in the Synclo editor.
Files of existing presentations
A file is generated with the presentation, through export. Download other files from the editor.
Callbacks
Synclo doesn't call your server when a generation completes. Poll GET /generations/{id}.
Social posts and webpages
format is slides or document.

Questions

Anything else: support@synclo.app.

How long does a generation take?

Most complete in one to three minutes. Poll every 5 seconds. A generation still running after 15 minutes fails with timed_out and isn't charged.

How much does a generation cost?

The same as in the app: 10 credits per slide from the workspace's balance, with images on auto included. Other image models may add credits per image. Failed generations aren't charged.

How do I know when a generation is complete?

Poll it. POST /generations returns the generation's id immediately; call GET /generations/{id} every 5 seconds until status is completed or failed.

Can I use the API from Zapier, Make or n8n?

Yes, with their HTTP steps: Webhooks by Zapier (Custom Request), the HTTP module in Make, or the HTTP Request node in n8n. Send the key in the Authorization header, create the generation with a POST, then repeat a GET until status is completed.

Can Claude or ChatGPT make presentations with Synclo?

Yes, through the connector, on every plan, with no API key: the person signs in with their Synclo account. Developers can connect any MCP client to the MCP server.

Which plans include the API?

Pro, Max and Business. Workspace admins create keys in Settings › API; a key uses its workspace's credits.

Who can open the file link?

Anyone with the URL, for 7 days: export.url requires no authentication. Store it as securely as the key, or download the file and serve it yourself.

Can I edit a generated presentation?

Yes, in the Synclo editor: every generated presentation is saved in the workspace, and document.edit_url opens it. The API itself doesn't edit presentations.