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
Go to Account Settings (click the setting icon in the bottom left, then select Account Settings).
Navigate to the API section.
Click Create new key.
Enter a name for your key (e.g., "Production Bot Access").
Optionally set an expiration date.
Click Create.
Copy your key immediately, it will only be shown once. Store it securely (e.g., in a
.envfile).
2. Find your agent's slug
Open the agent you want to access.
Click the Settings icon (gear icon) on your agent.
Go to the API tab.
Copy the text in the Agent slug section. This is the unique identifier you'll use as the
modelparameter.
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
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_callsare present, but may contain accompanying text from the model.finish_reasonis"tool_calls"(not"stop")argumentsis 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:
Initial delta with
role: "assistant"Content deltas (if text is generated before tool calls)
Tool call deltas with complete
argumentsin one chunkFinal delta with
finish_reason: "tool_calls"Optional usage chunk if
stream_options.include_usage: truedata: [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 textimage_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.contentCase 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:
Limitations
Parallel tool calls depend on the underlying model capability of your agent; the response structure supports multiple
tool_callsentriesNo n > 1: Only one choice is ever returned, even if
nis 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
toolsorexternalToolsfor 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
sessionIdto maintain context.Stream for better UX: Use
stream=Trueto show responses in real-time.Prefer externalTools or tools: Avoid relying on XML system prompt parsing unless you're integrating with Cline.