Access Swiftask agents via OpenAI SDK (recommended)

Written By Stanislas

Last updated 3 days ago

Overview

Swiftask agents are compatible with the OpenAI SDK. This means you can use any OpenAI client library (Python, JavaScript, Node.js, or others) to send messages to your agents and receive responses, just as you would with OpenAI's GPT models.

No special integration code is needed. You simply point the SDK to Swiftask's API endpoint, authenticate with your Swiftask API key, and specify your agent's slug as the model name. The SDK handles the rest.

This is useful when you want to integrate Swiftask agents into applications, scripts, or workflows that already use the OpenAI SDK, or when you prefer the familiar OpenAI interface.


Prerequisites

Before you can use the API, you need:

  • A Swiftask account with at least one agent created.

  • An API key: generated from your account settings.

  • Your agent's slug: a unique identifier found in your agent's settings.

  • An OpenAI SDK installed in your project (Python, JavaScript, etc.).


Configuration

Base URL: https://api.swiftask.fr/v1

Authentication: Swiftask API key (available in Account Settings β†’ API)

Model parameter: Your agent's slug (available in Agent Settings β†’ API tab)


Step-by-step setup

1. Get your API key

  1. Go to Account Settings (click the setting icon in the bottom left, then select Account Settings).

  2. Navigate to the API section.

  3. Click Create new key.

  4. Enter a name for your key (e.g., "Production Bot Access").

  5. Optionally set an expiration date.

  6. Click Create.

  7. Copy your key immediately, it will only be shown once. Store it securely (e.g., in a .env file).

2. Find your agent's slug

  1. Open the agent you want to access.

  2. Click the Settings icon (gear icon) on your agent.

  3. Go to the API tab.

  4. Copy the text in the Agent slug section. This is the unique identifier you'll use as the model parameter.

3. Install the OpenAI SDK

Choose your language and install the SDK:

Python:

pip install openai 

JavaScript / Node.js:

npm install openai 

4. Configure the SDK and make a basic request

Use your API key and agent slug to configure the client. Here are examples:

Python:

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",    
    base_url="https://api.swiftask.fr/v1"
)

response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[
        {"role": "user", "content": "Hello, how can you help me?"}
    ]
)

print(response.choices[0].message.content)

JavaScript / TypeScript:

import OpenAI from 'openai';

const client = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.swiftask.fr/v1',
});

const response = await client.chat.completions.create({
    model: 'AGENT_SLUG',
    messages: [
        { role: 'user', content: 'Hello, how can you help me?' }
    ]});

console.log(response.choices[0].message.content);

Key parameters

Parameter

Type

Parameter Type Description

model

string

Your agent's slug (required)

messages

array

Conversation history with roles (user, assistant, tool)

tools

array

OpenAI-compatible function definitions for function calling

externalTools

array

Swiftask custom field for tool definitions (takes priority over tools)

tool_choice

string/object

Controls tool invocation: "auto", "none", or {type:"function",function:{name:"..."}}

stream

boolean

Enable real-time streaming of responses

stream_options.include_usage

boolean

Include token usage in streaming responses

temperature

number

Controls randomness (0–2, default 1)

top_p

number

Nucleus sampling parameter (0–1)

max_tokens

number

Maximum tokens in response

presence_penalty

number

Penalizes new tokens based on prior appearance

frequency_penalty

number

Penalizes tokens based on frequency in prior text

response_format

object

{ "type": "text" | "json_object" }

stop

string/array

Sequences where the model stops generating

seed

number

For reproducible outputs

logit_bias

object

Adjust likelihood of specific tokens

user

string

Unique identifier for end-user (for tracking)

sessionId

number

Continue an existing Swiftask conversation session

documentAnalysisMode

string

"SIMPLE" | "ADVANCED" for file parsing

files

array

Files at request body level (in addition to message content)

extraConfig

object

Advanced backend configuration (passed directly to engine)


Function/Tool calling

Swiftask supports three methods to define tools for your agent. They work in priority order:

Method 1: externalTools (Swiftask-specific, highest priority)

Use the externalTools field with JSON Schema definitions. This is the recommended approach if you want to avoid conflicts with other uses of the standard tools field.

response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[
        {"role": "user", "content": "What is the weather in Paris?"}
    ],
    extra_body={
        "externalTools": [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Get the current weather in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state"
                        },
                        "unit": {
                            "type": "string",
                            "enum": ["celsius", "fahrenheit"]
                        }
                    },
                    "required": ["location"]
                }
            }
        }
    ]
    }

)

Method 2: tools (Standard OpenAI format)

Use the standard OpenAI tools field if externalTools is not provided. Format is identical to OpenAI's function calling specification.

response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[
        {"role": "user", "content": "What is the weather in Paris?"}
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Get the current weather in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {"type": "string"},
                        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                    },
                    "required": ["location"]
                }
            }
        }
    ],
    tool_choice="auto"
)

Method 3: XML system prompt (fallback mode)

If neither tools nor externalTools is provided, the backend attempts to parse tool definitions from your system prompt using a strict XML format. This is a best-effort fallback, primarily for compatibility with Cline and similar tools.

Expected format:

## tool_name
Description: Description of what this tool does.
Parameters:
- param1: (required) Description of param1.
- param2: (optional) Description of param2.
Usage:
<tool_name>
<param1>value</param1>
<param2>value</param2>
</tool_name>

Important notes:

  • The tool name line must match the regex: ^##\s+([a-zA-Z0-9_-]+)\s*$

  • Must include literal "Description:" and "Parameters:" labels

  • Parameter types are auto-detected: boolean if name contains "boolean" or is "recursive"/"requires_approval"; integer if contains "integer" or is "timeout"; object if contains "json object"; otherwise string.

  • This mode is not guaranteed; a slightly different format will not be parsed.


Tool choice parameter

Control when and how tools are invoked:

# Auto mode: model decides if a tool is needed
tool_choice="auto"

# None mode: model never calls tools
tool_choice="none"

# Force specific tool
tool_choice={
    "type": "function",
    "function": {"name": "get_current_weather"}
}

Response format: Non-streaming

When the model decides to call a tool, the response includes tool_calls and finish_reason: "tool_calls":

{
  "id": "chatcmpl-xxxxx",
  "object": "chat.completion",
  "created": 1234567890,
  "model": "mon-agent-slug",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_current_weather",
              "arguments": "{\"location\":\"Paris\",\"unit\":\"celsius\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 150,
    "completion_tokens": 50,
    "total_tokens": 200
  }
}

Key details:

  • content is usually null when tool_calls are present, but may contain accompanying text from the model.

  • finish_reason is "tool_calls" (not "stop")

  • arguments is a complete JSON string, not fragmented


Response format: Streaming

In streaming mode (stream=True), the backend sends Server-Sent Events (SSE). Tool call arguments are sent complete in a single chunk, not token-by-token like OpenAI.

response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[...],
    tools=[...],
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.tool_calls:
        print(chunk.choices[0].delta.tool_calls[0].function.arguments)

Stream structure:

  1. Initial delta with role: "assistant"

  2. Content deltas (if text is generated before tool calls)

  3. Tool call deltas with complete arguments in one chunk

  4. Final delta with finish_reason: "tool_calls"

  5. Optional usage chunk if stream_options.include_usage: true

  6. data: [DONE]


Complete tool calling round-trip example

Here's a full example showing the complete cycle: request β†’ tool call response β†’ tool result β†’ next request.

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.swiftask.fr/v1"
)

# Step 1: Initial request with tool definitions
response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[
        {"role": "user", "content": "What is the weather in Paris?"}
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Get current weather",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {"type": "string"}
                    },
                    "required": ["location"]
                }
            }
        }
    ]
)

# Step 2: Check if tool was called
if response.choices[0].finish_reason == "tool_calls":
    tool_call = response.choices[0].message.tool_calls[0]
    tool_name = tool_call.function.name
    tool_args = tool_call.function.arguments
    
    # Step 3: Execute the tool (simulated here)
    import json
    args = json.loads(tool_args)
    weather_result = f"Sunny, 18Β°C in {args['location']}"
    
    # Step 4: Send tool result back to the model
    response = client.chat.completions.create(
        model="AGENT_SLUG",
        messages=[
            {"role": "user", "content": "What is the weather in Paris?"},
            {
                "role": "assistant",
                "content": None,
                "tool_calls": [
                    {
                        "id": tool_call.id,
                        "type": "function",
                        "function": {
                            "name": tool_name,
                            "arguments": tool_args
                        }
                    }
                ]
            },
            {
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": weather_result
            }
        ],
        tools=[...]  # Must include tools again
    )
    
    # Step 5: Get final response
    print(response.choices[0].message.content)

With streaming (real-time)

If you want to receive responses in real-time as they're generated, enable streaming:

Python:

response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[{"role": "user", "content": "Analyze this document"}],
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

JavaScript / TypeScript:

const response = await client.chat.completions.create({
    model: 'AGENT_SLUG',
    messages: [
        { role: 'user', content: 'Tell me a story.' }
    ],
    stream: true,});

for await (const chunk of response) {
    if (chunk.choices[0].delta.content) {
        process.stdout.write(chunk.choices[0].delta.content);
    }
}

Multimodal content

Messages can include text, images, and files:

response = client.chat.completions.create(
    model="AGENT_SLUG",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What is in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/image.jpg",
                        "detail": "auto"  # or "low", "high"
                    }
                }
            ]
        }
    ]
)

Supported content types:

  • text: Plain text

  • image_url: URL (http/https or base64 data URI)

  • file: Base64-encoded file with filename


Practical use cases

Case 1: Integrate an agent into a support chatbot

You have a customer support agent in Swiftask and want to use it in your Node.js support application.

from openai import OpenAI

client = OpenAI(
    api_key="SWIFTASK_API_KEY",
    base_url="https://api.swiftask.fr/v1"
)

def answer_customer_question(question):
    response = await client.chat.completions.create(
        model="support_agent_slug",
        messages=[
            {"role": "user", "content": question}
        ]
    )
    return response.choices[0].message.content

Case 2: Batch process documents with an agent

You have a document analysis agent and want to process 100 documents in a Python script.

from openai import OpenAI

client = OpenAI(
    api_key="SWIFTASK_API_KEY",
    base_url="https://api.swiftask.fr/v1"
)

documents = ["Doc 1 content...", "Doc 2 content..."]

for doc in documents:
    response = client.chat.completions.create(
        model="document_analyzer_slug",
        messages=[
            {"role": "user", "content": f"Analyze: {doc}"}
        ]
    )
    print(response.choices[0].message.content)

Case 3: Use tool calling to fetch data

You want to display agent responses in real-time on a web page.

# Agent calls a tool to retrieve customer data
response = client.chat.completions.create(
    model="sales_agent_slug",
    messages=[
        {"role": "user", "content": "Get details for customer ID 12345"}
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "get_customer_details",
                "description": "Retrieve customer information",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "customer_id": {"type": "string"}
                    },
                    "required": ["customer_id"]
                }
            }
        }
    ]
)

Error handling

All errors follow the standard OpenAI format:

{
  "error": {
    "message": "Invalid API Key",
    "type": "authentication_error",
    "param": null,
    "code": null
  }
}

Common errors:

Status

Error

Cause

Solution

401

Invalid API Key

Missing or expired API key

Check Account Settings β†’ API

400

Bot not found

Agent slug is incorrect

Verify agent slug in Agent Settings

400

Invalid request

Malformed JSON or missing required fields

Check request body structure

500

Server error

Backend issue

Contact support


Limitations

  • Parallel tool calls depend on the underlying model capability of your agent; the response structure supports multiple tool_calls entries

  • No n > 1: Only one choice is ever returned, even if n is specified.

  • Tools must be re-sent: The server does not memorize tools between requests; include them with every call.

  • XML parsing is best-effort: The system prompt parsing mode is not guaranteed; use tools or externalTools for reliability.


Tips & best practices

  • Keep API keys secure: Never commit them to version control. Use environment variables.

  • Re-include tools in every request: Even if you're continuing a conversation, always send the tools array.

  • Use sessionId for context: If you're continuing a Swiftask session, include sessionId to maintain context.

  • Stream for better UX: Use stream=True to show responses in real-time.

  • Prefer externalTools or tools: Avoid relying on XML system prompt parsing unless you're integrating with Cline.


Additional resources