ModelFold PPT 1.1
A model built by ModelFold. Send a topic (optionally with notes, facts or an article) and get back a complete, editable presentation:
- an outline first, then every slide written in batches so the deck stays coherent;
- 6–50 slides in 10 layouts: cover, agenda, section divider, bullets, two columns, image + text, big numbers, quote, timeline, closing;
- 6 themes (
midnight/corporate/paper/forest/sunset/mono) with shared palette, fonts, page numbers, footer and logo area on every slide; - optional AI images, generated only for layouts that need them;
- output as PPTX (text boxes and shapes are native, editable PowerPoint objects), PDF, PNG (ZIP) and the Studio document JSON;
- every deck is saved to the caller's Studio; the returned
studio_urlopens it for further editing.
Overview
| Field | Value |
|---|---|
| Model ID | modelfold-ppt-1.1 |
| Type | Office / presentation (document) |
| Protocol | Async jobs: POST /api/v1/jobs/createTask + GET /api/v1/jobs/recordInfo |
| Auth | Authorization: Bearer <API key> |
| Latency | Usually 30–90 seconds; longer with AI images |
| File retention | 30 days (same as other generated files) |
Pricing
Price per deck = base + per-slide price × slides + per-image price × images actually generated.
| Item | Default (credits) |
|---|---|
| Base per deck | 3 |
| Per slide | 0.5 |
| Per AI image | 6 (= the site's image-model price + 1; follows the markup setting) |
Credits for the maximum possible number of images (min(12, ceil(slides × 0.4))) are reserved when the task is created and settled to the images actually generated; failed tasks are refunded in full. Examples: 8 slides without images, 7 credits; 10 slides with 4 images, 32 credits. See the model page for current prices.
Parameters (inside input)
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
prompt | string | Yes | — | Topic or one-sentence brief, 2–1000 characters. Alias: topic. |
content | string | No | — | Source material: notes, facts or an article, up to 20000 characters. Alias: notes. |
slides | integer | No | 10 | Number of slides, 6–50. |
language | string | No | en | Text language: zh en ja es ko fr de pt. |
theme | string | No | midnight | midnight corporate paper forest sunset mono. |
template | string | No | — | Own template ID or public design ID. Overrides the selected built-in theme. |
ai_images | boolean | No | true | Generate AI images (billed per generated image). |
output_formats | string[] | No | ["pptx"] | Any of pptx, pdf, png (ZIP with one PNG per slide), json (Studio document). |
Optional top-level callBackUrl + callbackSecret (completion callback) and the Idempotency-Key header work exactly as for other async models; see Async jobs.
Request examples
curl -X POST https://ai.modelfold.online/api/v1/jobs/createTask \
-H "Authorization: Bearer $MODELFOLD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "modelfold-ppt-1.1",
"input": {
"prompt": "Quarterly business review for our AI video product",
"content": "Q3 revenue +38%, 12k paying users, NPS 64; next quarter: international and enterprise",
"slides": 10,
"language": "en",
"theme": "corporate",
"template": "TEMPLATE_ID",
"ai_images": true,
"output_formats": ["pptx", "pdf"]
}
}'
# {"code":200,"msg":"success","data":{"taskId":"…","state":"queued","credits":27}}
curl "https://ai.modelfold.online/api/v1/jobs/recordInfo?taskId=TASK_ID" \
-H "Authorization: Bearer $MODELFOLD_API_KEY"import os, time, json, requests
API = "https://ai.modelfold.online/api/v1/jobs"
H = {"Authorization": f"Bearer {os.environ['MODELFOLD_API_KEY']}"}
task = requests.post(f"{API}/createTask", headers=H, json={
"model": "modelfold-ppt-1.1",
"input": {"prompt": "Onboarding training for new sales hires", "slides": 8, "theme": "paper", "template": "TEMPLATE_ID", "ai_images": False},
}).json()["data"]
while True:
job = requests.get(f"{API}/recordInfo", headers=H, params={"taskId": task["taskId"]}).json()["data"]
if job["state"] in ("success", "fail"):
break
time.sleep(5)
result = json.loads(job["resultJson"])["resultObject"]
open("deck.pptx", "wb").write(requests.get(result["files"]["pptx"]).content)const API = 'https://ai.modelfold.online/api/v1/jobs'
const headers = { Authorization: `Bearer ${process.env.MODELFOLD_API_KEY}`, 'Content-Type': 'application/json' }
const { data: task } = await fetch(`${API}/createTask`, { method: 'POST', headers,
body: JSON.stringify({ model: 'modelfold-ppt-1.1', input: { prompt: 'Coffee shop launch plan', slides: 8 } }) }).then((r) => r.json())
let job
do {
await new Promise((r) => setTimeout(r, 5000))
job = (await fetch(`${API}/recordInfo?taskId=${task.taskId}`, { headers }).then((r) => r.json())).data
} while (!['success', 'fail'].includes(job.state))
console.log(JSON.parse(job.resultJson).resultObject.files.pptx)Response
When state is success, resultJson is a JSON string: resultUrls lists every generated file and resultObject holds the structured result:
{
"title": "AI Video Product QBR",
"slides": 10,
"theme": "corporate",
"language": "en",
"template": "123",
"files": { "pptx": "https://…/modelfold-ppt-….pptx", "pdf": "https://…/modelfold-ppt-….pdf" },
"cover_url": "https://…/modelfold-ppt-…-cover.jpg",
"studio_url": "https://ai.modelfold.online/studio/edit/123",
"design_id": 123,
"ai_images": { "requested": true, "generated": 3 },
"outline": [{ "index": 1, "type": "cover", "title": "…", "points": ["…"] }],
"billing": { "credits": 26, "base": 3, "per_slide": 0.5, "per_image": 6 }
}| Field | Description |
|---|---|
files.pptx / files.pdf / files.png_zip / files.json | Files for the requested output_formats |
studio_url | Open the deck in ModelFold Studio (only the API key owner can open it) |
outline | Slide types, titles and key points |
ai_images | Requested / generated AI images |
billing | Final credits and breakdown (matches usage.credits) |
On failure state is fail, failMsg explains why, and the reserved credits are refunded in full.
Related
- All models
- Async jobs
- Try it online: AI Design Studio · Full slide deck
Optional uploaded template
Upload a PPTX (up to 12 MB) using POST /v1/studio/templates/upload with the same API key and JSON { "name": "brand.pptx", "data": "BASE64_PPTX" }. The response contains template_id. Pass "template": "123" inside input to use it, a saved Studio template, or a public design ID. Private templates require ownership. Uploaded originals are never publicly served. Basic theme colors, fonts, backgrounds, logos and text layouts are imported; complex charts, groups, animation and unsupported media are simplified or omitted, and missing fonts fall back. Review before use.
Long outlines are generated in chunks of up to 10 slides; slide content uses batches of 4, up to 3 concurrently. Allow several minutes for 50 slides. AI images are capped at 12. PDF rendering runs one page at a time to bound image memory.
Template IDs and image style
Uploading does not call a model. Use the same API key to create a deck and set input.template to the returned template_id string. It overrides theme; private templates are owner-only.
- GET /v1/studio/templates (authenticated): list your templates.
- GET /v1/studio/templates/public (anonymous): list real public/official IDs. Response: {"ok":true,"templates":[{"id":"123","title":"…","format":"slide","preview_url":null}]}. The list may be empty; query it instead of inventing official IDs.
- POST /v1/studio/templates/upload (authenticated): JSON name is a .pptx filename; data is plain Base64 without a data: prefix, maximum 12 MB. Response: {"ok":true,"template_id":"123","warnings":["pptx_simplified","font_fallback"],"design":{…}}. The original PPTX is not publicly downloadable.
- OOXML supplies palette, fonts, basic text geometry and master artwork. The existing billed slide call inspects up to two non-logo images for photography/illustration/flat/3D medium, lighting, composition and background texture, then explicitly includes that style in each imagePrompt. The same template mapping applies typography and basic layouts.
- Image generation prefers a reference-capable sibling (Seedream 5 Flash image-to-image or Nano Banana 2 Lite), sending up to two template images. Extracted assets are retained in uploads/studio; the original file stays private. Without artwork or model support, style is text-only; pixel-identical reproduction is not guaranteed. Complex charts/groups/animations and unavailable fonts are simplified.
- ai_images=false generates and bills no images. Only successful images are billed, capped at min(12, ceil(slides × 0.4)). Vision is part of the existing billed slide call, with no separate analysis call. Result template echoes the ID, or null when omitted.
# Inspect public IDs, then upload a private template (Python avoids shell Base64 differences).
curl https://ai.modelfold.online/v1/studio/templates/public
python3 -c 'import base64,json; print(json.dumps({"name":"brand.pptx","data":base64.b64encode(open("brand.pptx","rb").read()).decode()}))' > template.json
curl https://ai.modelfold.online/v1/studio/templates/upload \
-H "Authorization: Bearer $MODELFOLD_API_KEY" -H "Content-Type: application/json" --data-binary @template.json
curl https://ai.modelfold.online/v1/studio/templates -H "Authorization: Bearer $MODELFOLD_API_KEY"
# Use returned template_id in input.template in the createTask examples above.import base64, os, requests
base = "https://ai.modelfold.online"
headers = {"Authorization": "Bearer " + os.environ["MODELFOLD_API_KEY"]}
public = requests.get(base + "/v1/studio/templates/public").json()["templates"]
with open("brand.pptx", "rb") as f:
uploaded = requests.post(base + "/v1/studio/templates/upload", headers=headers,
json={"name": "brand.pptx", "data": base64.b64encode(f.read()).decode()})
uploaded.raise_for_status()
template_id = uploaded.json()["template_id"]
response = requests.post(base + "/api/v1/jobs/createTask", headers=headers,
json={"model": "modelfold-ppt-1.1", "input": {"prompt": "Brand launch plan",
"slides": 6, "template": template_id, "ai_images": True, "output_formats": ["pptx", "json"]}})
response.raise_for_status()
print(response.json()) # Poll recordInfo as above; check state=success before reading resultJson.import { readFile } from 'node:fs/promises'
const base = 'https://ai.modelfold.online'
const headers = { Authorization: `Bearer ${process.env.MODELFOLD_API_KEY}`, 'Content-Type': 'application/json' }
const publicTemplates = await fetch(base + '/v1/studio/templates/public').then(r => r.json())
const upload = await fetch(base + '/v1/studio/templates/upload', { method: 'POST', headers,
body: JSON.stringify({ name: 'brand.pptx', data: (await readFile('brand.pptx')).toString('base64') }) })
if (!upload.ok) throw new Error(await upload.text())
const { template_id } = await upload.json()
const task = await fetch(base + '/api/v1/jobs/createTask', { method: 'POST', headers,
body: JSON.stringify({ model: 'modelfold-ppt-1.1', input: { prompt: 'Brand launch plan',
slides: 6, template: template_id, ai_images: true, output_formats: ['pptx', 'json'] } }) }).then(r => r.json())
console.log(task) // Poll recordInfo as above; check state=success before reading resultJson.