A common flow is simple: an assistant or AI tool drafts the script, your system saves it to Speakflow, and the presenter opens the returned URL when it is time to record.
-
1
Generate a key
Open Account Settings -> API Keys, create a workspace-scoped key, and copy the sfk_ token immediately. It is only shown once.
-
2
Send authenticated requests
Call https://www.speakflow.com/api/v1 with Authorization: Bearer sfk_..., write scripts into the key's scoped workspace, and set each script's language for voice recognition.
-
3
Open the script
After you create or update a script, use the returned script URL to open it in Speakflow.
Use this reference to authenticate with an API key, create or update scripts, and manage labels and workspaces from your tools.
Base URL: https://www.speakflow.com/api/v1
Authentication
This reference covers Speakflow API keys (sfk_ prefix) passed as a Bearer token:
Authorization: Bearer sfk_your_key_hereCreating an API key
API keys require a paid plan. If you're on a free workspace, Speakflow will prompt you to upgrade before you can create one.
- Go to Account Settings > API Keys
- Click Create Key
- Give it a name and select a workspace
- Copy the key immediately — you won't be able to see it again
API keys are scoped to a single workspace. Any scripts you create with a key are automatically saved to that workspace.
Key behavior
- Keys have full read/write access within their scoped workspace
- Keys never expire unless manually revoked
- Keys stop working if the key owner no longer has a paid plan
- You can revoke a key at any time from the API Keys settings page
- Each key tracks when it was last used
Endpoints
Get current user
Returns information about the authenticated user.
GET /api/v1/userExample:
curl https://www.speakflow.com/api/v1/user \
-H "Authorization: Bearer sfk_your_key_here"Response:
{
"user": {
"id": 123,
"email": "you@example.com",
"first_name": "Jane",
"last_name": "Doe",
"team": "My Team",
"profile_picture_url": "https://...",
"plan_name": "Plus",
"active_subscription": true,
"subscription_end_date": "2026-04-15",
"created_at": "2025-01-10T08:00:00Z",
"updated_at": "2026-03-14T12:30:00Z",
"use_case": "sales"
}
}List scripts
Returns scripts in the API key's workspace. Results default to 25 scripts per page and can be increased to 100 with limit. Pass the cursor from pagination.next as page to request the next page.
Use sort to order results by last_updated, alphabetical, or date_created, and use direction with asc or desc. If omitted, Speakflow uses the key owner's saved script order, falling back to most recently updated first.
Script, workspace, and folder IDs in this API are returned as obfuscated strings. Use those values when calling related endpoints.
GET /api/v1/scriptsExample:
curl https://www.speakflow.com/api/v1/scripts \
-H "Authorization: Bearer sfk_your_key_here"Response:
{
"scripts": [
{
"id": "QbLmXy",
"title": "Product Demo Script",
"preview": "Welcome everyone, today I'll be walking you through...",
"workspace_id": "NwPqRs",
"folder_id": null,
"source": "web",
"language": "en-US",
"created_at": "2026-03-10T14:00:00Z",
"updated_at": "2026-03-14T09:00:00Z",
"url": "https://www.speakflow.com/account/scripts/abc123",
"script_url": "https://www.speakflow.com/account/scripts/abc123"
}
],
"pagination": {
"next": null,
"has_more": false,
"limit": 25
}
}Get a script
Returns a single script with its full content.
GET /api/v1/scripts/:idExample:
curl https://www.speakflow.com/api/v1/scripts/QbLmXy \
-H "Authorization: Bearer sfk_your_key_here"Response:
{
"script": {
"id": "QbLmXy",
"title": "Product Demo Script",
"content": "Welcome everyone, today I'll be walking you through our product...",
"preview": "Welcome everyone, today I'll be walking you through...",
"workspace_id": "NwPqRs",
"folder_id": null,
"source": "web",
"language": "en-US",
"created_at": "2026-03-10T14:00:00Z",
"updated_at": "2026-03-14T09:00:00Z",
"url": "https://www.speakflow.com/account/scripts/abc123",
"script_url": "https://www.speakflow.com/account/scripts/abc123",
"labels": [
{ "id": 1, "name": "Sales", "color": "#4f46e5" }
]
}
}Create a script
Creates a new script in the API key's workspace.
POST /api/v1/scriptsParameters:
| Field | Type | Required | Description |
|---|---|---|---|
script[title] | string | No | The script title. Speakflow supplies an untitled display name when omitted. |
script[body] | string | Yes | The full script content (plain text or HTML). The key must be present, but it may contain an empty string for a blank draft. |
script[source] | string | No | Source tag for the script, such as web or chatgpt. Defaults to web. |
script[language] | string | No | Language used for voice recognition, such as en-US or de-DE. Defaults to en-US. |
script[workspace_id] | string | No | OAuth clients can target an accessible workspace. API-key requests always use the key's scoped workspace and cannot override it. |
script[folder_id] | string | No | Target folder within the selected workspace. Use the obfuscated folder ID returned by the API |
script[label_ids] | array | No | Array of label IDs to apply |
Example:
curl -X POST https://www.speakflow.com/api/v1/scripts \
-H "Authorization: Bearer sfk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"script": {
"title": "My New Script",
"body": "This is the script content that will appear in the teleprompter.",
"language": "de-DE"
}
}'Response (201 Created):
{
"script": {
"id": "AbCdEf",
"title": "My New Script",
"content": "This is the script content that will appear in the teleprompter.",
"preview": "This is the script content that will appear in the...",
"workspace_id": "NwPqRs",
"folder_id": null,
"source": "web",
"language": "de-DE",
"created_at": "2026-03-15T10:00:00Z",
"updated_at": "2026-03-15T10:00:00Z",
"url": "https://www.speakflow.com/account/scripts/def456",
"script_url": "https://www.speakflow.com/account/scripts/def456",
"labels": []
}
}Update a script
Updates an existing script.
PATCH /api/v1/scripts/:idParameters: Same as create — only include fields you want to change. You can also pass script[base_updated_at] as an ISO 8601 timestamp for conflict detection. If the script changed after that timestamp, Speakflow returns a 409 response with the current server version.
Example:
curl -X PATCH https://www.speakflow.com/api/v1/scripts/AbCdEf \
-H "Authorization: Bearer sfk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"script": {
"body": "Updated script content for today's presentation."
}
}'Response (200 OK):
{
"script": {
"id": "AbCdEf",
"title": "My New Script",
"content": "Updated script content for today's presentation.",
"preview": "Updated script content for today's presentation.",
"workspace_id": "NwPqRs",
"folder_id": null,
"source": "web",
"language": "de-DE",
"created_at": "2026-03-15T10:00:00Z",
"updated_at": "2026-03-15T10:05:00Z",
"url": "https://www.speakflow.com/account/scripts/def456",
"script_url": "https://www.speakflow.com/account/scripts/def456",
"labels": []
}
}Delete a script
Permanently deletes a script.
DELETE /api/v1/scripts/:idExample:
curl -X DELETE https://www.speakflow.com/api/v1/scripts/AbCdEf \
-H "Authorization: Bearer sfk_your_key_here"Response: 204 No Content
List labels
Returns all labels for the current team.
GET /api/v1/labelsExample:
curl https://www.speakflow.com/api/v1/labels \
-H "Authorization: Bearer sfk_your_key_here"Response:
{
"labels": [
{ "id": 1, "name": "Sales", "color": "#4f46e5", "scripts_count": 12 },
{ "id": 2, "name": "Training", "color": "#059669", "scripts_count": 5 }
]
}Create a label
POST /api/v1/labelsParameters:
| Field | Type | Required | Description |
|---|---|---|---|
label[name] | string | Yes | Label name |
label[color] | string | No | Hex color code |
Update a label
PATCH /api/v1/labels/:idDelete a label
DELETE /api/v1/labels/:idResponse: 204 No Content
List workspaces
Returns workspaces accessible to the authenticated user. If using an API key, returns only the key's scoped workspace.
GET /api/v1/workspacesExample:
curl https://www.speakflow.com/api/v1/workspaces \
-H "Authorization: Bearer sfk_your_key_here"Response:
{
"workspaces": [
{
"id": "NwPqRs",
"name": "My Workspace",
"team_name": "My Team",
"is_default": true,
"scripts_count": 42
}
]
}Error responses
Most errors follow this format:
{
"error": "error_code",
"error_description": "Human-readable description"
}| Status | Error Code | Description |
|---|---|---|
| 401 | unauthorized | Invalid or expired API key |
| 403 | access_denied | Key doesn't have access to this resource |
| 403 | insufficient_scope | Missing required scope |
| 404 | not_found | Resource not found |
| 409 | conflict | base_updated_at is stale; the response includes the current server script |
| 422 | validation_failed | Invalid parameters (details in error_description) |
| 429 | rate_limit_exceeded | Rate limit exceeded (100 requests/hour per IP) |
Rate limits
API requests are limited to 100 requests per hour per IP address. If you exceed this limit, you'll receive a 429 response with error: "rate_limit_exceeded".
Use with AI tools
Model Context Protocol (MCP)
Speakflow provides a stateless Streamable HTTP MCP server:
https://www.speakflow.com/mcp#### Connect with Claude
- In Claude, open Settings → Connectors and choose Add custom connector.
- Name the connector Speakflow and enter
https://www.speakflow.com/mcp. - Sign in to Speakflow and approve read and write access.
The OAuth connection uses your current Speakflow team's default accessible workspace and requires a paid Speakflow plan. Access tokens expire after one hour and refresh automatically. Disconnect the connector in Claude to stop its use, and revoke the authorized application in Speakflow to invalidate its tokens.
Other MCP clients can use the same OAuth discovery flow. Clients that support custom Bearer headers can alternatively use the same workspace-scoped API key as the REST API:
Authorization: Bearer sfk_your_key_hereThe MCP server exposes tools to inspect the connected account and workspace, list and read scripts, create or update scripts, delete a script, and list available labels. Script writes stay inside the authenticated workspace. Updates support base_updated_at conflict detection, and create responses include script_url so the presenter can open the result immediately. Script content returned by a tool is capped at 30,000 characters to stay within client response limits.
Use Accept: application/json, text/event-stream and Content-Type: application/json when connecting over Streamable HTTP. The server is stateless, so it does not return an MCP-Session-Id.
ChatGPT (Custom GPT Actions)
You can create a Custom GPT that writes scripts directly to your Speakflow teleprompter:
- Create a new GPT in ChatGPT
- Add an Action for the Speakflow endpoints you want the GPT to call
- Configure Bearer authentication with your
sfk_API key - Instruct the GPT to create/update scripts based on your prompts
Public API access uses API keys. OAuth is not available for external developers.
Example GPT instruction: > "When the user asks you to write or update a script, call the Speakflow API and include the returned script_url in your reply so they can open it in Speakflow."
Claude prompt examples
After connecting Speakflow, try:
Create a 2-minute product demo script and save it to my Speakflow teleprompter.Show me the five Speakflow scripts I updated most recently.Rewrite my “Quarterly kickoff” script with a stronger opening, then update it without overwriting any newer edits.Delete the draft named “Old webinar test.” Ask me to confirm before deleting it.If connection fails, confirm that the URL is exactly https://www.speakflow.com/mcp, that your Speakflow subscription is active, and that your current team has an accessible workspace. Reconnect to grant updated permissions. For help, visit Speakflow Support or email team@speakflow.com.
Any AI tool or CLI
Any tool that can make HTTP requests can integrate with Speakflow:
# Generate a script with an AI, then push it to Speakflow
echo "Your generated script content" | \
curl -X POST https://www.speakflow.com/api/v1/scripts \
-H "Authorization: Bearer sfk_your_key_here" \
-H "Content-Type: application/json" \
-d "{\"script\": {\"title\": \"AI-Generated Script\", \"body\": \"$(cat)\"}}"