DeckFlow Logo Developers DeckFlow documentation
Developer GuideAPI ReferenceMCPCLI

Quick Start

The quick start guide for DeckFlow developers to establish the shortest path for file uploading, task creation, status querying, and result downloading.

DeckFlow API utilizes an asynchronous task model for most file operations, supporting multi-language translation, revamp (redesign), and generation of various documents and presentation decks.


Core Steps

Step 1: Get & Configure API Key

Before getting started, log in to DeckFlow and generate your API Key in the settings page.

Configure environment variables to begin using the API:

# Configure API key and base path
export DECKFLOW_API_KEY="Bearer <YOUR_API_KEY>"
export DECKFLOW_API_BASE="https://app.deckflow.com/api"

For more detailed information, see API Key.


Step 2: Submit a Task

All task submissions (including generation, translation, revamp, and other tool APIs) are posted to a unified task management endpoint using a single-step multipart/form-data format. There is no need to pre-upload files; simply pass your file binary and parameters directly within the request body.

  • Request Path: POST /tools/tasks
  • Request Headers:
    • Authorization: Bearer <YOUR_API_KEY>
    • Content-Type: multipart/form-data
  • Primary Parameters:
    • files: Local file binary.
    • type: Task type, e.g. translation.
    • params: JSON string parameter configuration, e.g., {"from":"zh","to":"en"}.

The following snippets demonstrate how to submit a translation task:

curl -X POST "$DECKFLOW_API_BASE/tools/tasks" \
  -H "Authorization: $DECKFLOW_API_KEY" \
  --form 'files=@"/path/to/presentation.pptx"' \
  --form 'type="translation"' \
  --form 'params="{\"from\":\"zh\",\"to\":\"en\"}"'
const formData = new FormData();
formData.append('files', fileInput.files[0]); // Local PPTX/PDF/Word file
formData.append('type', 'translation');
formData.append('params', JSON.stringify({ from: 'zh', to: 'en' }));

const response = await fetch(`${process.env.DECKFLOW_API_BASE}/tools/tasks`, {
  method: 'POST',
  headers: {
    'Authorization': process.env.DECKFLOW_API_KEY
  },
  body: formData
});
const task = await response.json();
console.log('Created Task:', task);
import os, requests

url = f"{os.environ['DECKFLOW_API_BASE']}/tools/tasks"
headers = {
    "Authorization": os.environ["DECKFLOW_API_KEY"]
}
files = [
    ("files", ("presentation.pptx", open("presentation.pptx", "rb"), "application/vnd.openxmlformats-officedocument.presentationml.presentation"))
]
data = {
    "type": "translation",
    "params": '{"from":"zh","to":"en"}'
}

response = requests.post(url, headers=headers, files=files, data=data)
print('Created Task:', response.json())

Once successfully created, the server returns a JSON response containing the id (representing taskId) with status pending.


Step 3: Get Task Status & Results

Since document processing takes some time, you need to use the taskId to fetch the progress. DeckFlow supports both Polling and Server-Sent Events (SSE) stream subscription to retrieve status and results.

  • Request Path: GET /tools/tasks/{taskId}

Method A: Real-time Subscription (SSE) Recommended

By specifying the response-event-stream: yes header, the server pushes progress events in real-time. The connection will close automatically once the task finishes, saving bandwidth and connection overhead.

curl -X GET "$DECKFLOW_API_BASE/tools/tasks/YOUR_TASK_ID" \
  -H "Authorization: $DECKFLOW_API_KEY" \
  -H "response-event-stream: yes"
const url = `${process.env.DECKFLOW_API_BASE}/tools/tasks/${taskId}`;
const response = await fetch(url, {
  headers: {
    'Authorization': process.env.DECKFLOW_API_KEY,
    'response-event-stream': 'yes'
  }
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value);
  const lines = chunk.split('\n');
  for (const line of lines) {
    if (line.startsWith('data:')) {
      const taskJSON = JSON.parse(line.replace('data:', '').trim());
      console.log('Received push status:', taskJSON.status);
      if (taskJSON.status === 'completed' || taskJSON.status === 'failed') {
        console.log('Final Result:', taskJSON);
        return;
      }
    }
  }
}
import os, requests, json

url = f"{os.environ['DECKFLOW_API_BASE']}/tools/tasks/{task_id}"
headers = {
    "Authorization": os.environ["DECKFLOW_API_KEY"],
    "response-event-stream": "yes"
}

response = requests.get(url, headers=headers, stream=True)
for line in response.iter_lines():
    if line:
        decoded_line = line.decode('utf-8')
        if decoded_line.startswith('data:'):
            task_json = json.loads(decoded_line.replace('data:', '').strip())
            print("Received push status:", task_json.get("status"))
            if task_json.get("status") in ["completed", "failed"]:
                print("Final Result:", task_json)
                break

Method B: Periodic Polling

The client sends requests periodically (e.g. every 3-5 seconds) to check status until the task enters a terminal state (completed or failed).

curl -X GET "$DECKFLOW_API_BASE/tools/tasks/YOUR_TASK_ID" \
  -H "Authorization: $DECKFLOW_API_KEY"
async function pollTask(taskId) {
  const url = `${process.env.DECKFLOW_API_BASE}/tools/tasks/${taskId}`;
  const headers = { 'Authorization': process.env.DECKFLOW_API_KEY };

  while (true) {
    const res = await fetch(url, { headers });
    const task = await res.json();
    console.log('Current status:', task.status);

    if (task.status === 'completed') {
      console.log('Success! Download URL:', task.result.url);
      break;
    } else if (task.status === 'failed') {
      console.error('Failed! Error:', task.error);
      break;
    }
    await new Promise(resolve => setTimeout(resolve, 3000));
  }
}
import os, requests, time

def poll_task(task_id):
    url = f"{os.environ['DECKFLOW_API_BASE']}/tools/tasks/{task_id}"
    headers = { "Authorization": os.environ["DECKFLOW_API_KEY"] }

    while True:
        response = requests.get(url, headers=headers)
        task = response.json()
        status = task.get("status")
        print("Current status:", status)

        if status == "completed":
            print("Success! Download URL:", task["result"]["url"])
            break
        elif status == "failed":
            print("Failed! Error:", task.get("error"))
            break
        time.sleep(3)

Step 4: Download Results

Once the status becomes completed, retrieve the temporarily signed download URL from result.url and save the output file locally.

Temporarily signed URLs have a limited expiration time. To preserve your processed files permanently, please download and save them to your own storage servers or databases before the link expires.