ResourcesClose AI

Close AI

Build Close AI desktop integrations with session analysis, prompt presets, coaching dashboards, scripts, and analytics settings through the Talkturo API.

{
  "sessions": [
    {
      "id": "sess_7f2c91a4",
      "user_id": "usr_a1b2c3d4",
      "account_id": "acct_4e5f6a7b",
      "title": "Discovery call with Northstar",
      "session_type": "sales_call",
      "started_at": "2025-02-12T14:00:00.000Z",
      "ended_at": "2025-02-12T14:32:18.000Z",
      "status": "completed",
      "duration_seconds": 1938,
      "updated_at": "2025-02-12T14:35:02.000Z"
    }
  ],
  "count": 1
}
{
  "session": {
    "id": "sess_7f2c91a4",
    "user_id": "usr_a1b2c3d4",
    "title": "Discovery call with Northstar",
    "session_type": "sales_call",
    "started_at": "2025-02-12T14:00:00.000Z",
    "ended_at": "2025-02-12T14:32:18.000Z",
    "status": "completed",
    "duration_seconds": 1938,
    "updated_at": "2025-02-12T14:35:02.000Z",
    "created_at": "2025-02-12T14:00:00.000Z",
    "parent_session_id": null
  },
  "transcripts": [
    {
      "id": "tr_91a2b3c4",
      "session_id": "sess_7f2c91a4",
      "start_at": "2025-02-12T14:00:04.000Z",
      "end_at": "2025-02-12T14:00:18.000Z",
      "speaker": "rep",
      "text": "Thanks for taking the time to meet today.",
      "lang": "en",
      "created_at": "2025-02-12T14:00:19.000Z"
    }
  ],
  "messages": [],
  "summary": null,
  "analysis": null
}
{
  "ok": true,
  "title": "Northstar discovery call"
}
{
  "ok": true,
  "deleted": true
}
{
  "analysis": {
    "session_id": "sess_7f2c91a4",
    "close_score": 82,
    "score_breakdown": {
      "discovery": 88,
      "objection_handling": 76,
      "next_steps": 82
    },
    "strengths": ["Clear discovery questions"],
    "weaknesses": ["Limited objection follow-up"],
    "risks": ["No confirmed procurement timeline"],
    "objections": [],
    "questions": {
      "open": 8,
      "closed": 3,
      "deep": 4,
      "missed": []
    },
    "personality": {
      "type": "analytical"
    },
    "talk_metrics": {
      "rep_talk_share_pct": 46,
      "words_per_minute": 132
    },
    "script_coverage": {
      "coverage_pct": 84
    },
    "language": "en",
    "model": "close-ai",
    "generated_at": "2025-02-12T14:40:00.000Z"
  }
}
{
  "presets": [
    {
      "id": "preset_8a2b3c4d",
      "user_id": "usr_a1b2c3d4",
      "title": "Discovery call review",
      "prompt": "Evaluate discovery depth, qualification, and next steps.",
      "is_default": true,
      "is_template": true,
      "created_at": "2025-02-10T09:00:00.000Z",
      "updated_at": "2025-02-12T10:15:00.000Z"
    }
  ]
}
{
  "preset": {
    "id": "preset_8a2b3c4d",
    "user_id": "usr_a1b2c3d4",
    "title": "Discovery call review",
    "prompt": "Evaluate discovery depth, qualification, and next steps.",
    "is_default": true,
    "is_template": false,
    "created_at": "2025-02-12T10:15:00.000Z",
    "updated_at": "2025-02-12T10:15:00.000Z"
  }
}
{
  "analytics_system_prompt": "Focus on discovery quality and measurable next steps.",
  "updated_at": "2025-02-12T10:15:00.000Z"
}
{
  "analytics_system_prompt": "Focus on discovery quality and measurable next steps.",
  "updated_at": "2025-02-12T10:20:00.000Z"
}
{
  "kpis": {
    "calls": 48,
    "callsDeltaPct": 12.5,
    "avgCloseScore": 76,
    "avgDurationSeconds": 1840,
    "activeMembers": 6,
    "analyzedCount": 41
  },
  "coaching": {
    "evaluations": 41,
    "strengths": [
      { "label": "Discovery", "count": 22 }
    ],
    "weaknesses": [
      { "label": "Objection handling", "count": 15 }
    ],
    "risks": [
      { "label": "Unclear next steps", "count": 9 }
    ]
  },
  "objections": {
    "total": 18,
    "byCategory": [
      { "key": "budget", "count": 8, "avgCloseScore": 71 }
    ],
    "byType": [
      { "key": "timing", "count": 5, "avgCloseScore": 74 }
    ],
    "byIntensity": [
      { "key": "high", "count": 3, "avgCloseScore": 62 }
    ]
  },
  "questions": {
    "open": 120,
    "closed": 64,
    "deep": 38,
    "missed": [
      { "label": "Decision process", "count": 7 }
    ]
  },
  "personality": [
    { "type": "analytical", "count": 16 }
  ],
  "language": {
    "avgTalkSharePct": 48,
    "avgWpm": 132,
    "avgPatiencePct": 72,
    "avgLongestMonologueSeconds": 46
  },
  "script": {
    "calls": 39,
    "avgCoveragePct": 81,
    "avgOrderDeviationPct": 14,
    "blocks": [
      { "name": "Discovery", "avgPct": 91 }
    ]
  },
  "scores": {
    "distribution": [
      { "bucket": "0-39", "count": 2 },
      { "bucket": "40-59", "count": 7 },
      { "bucket": "60-79", "count": 20 },
      { "bucket": "80-100", "count": 12 }
    ],
    "avg": 76
  },
  "durationDistribution": [
    { "bucket": "0-5m", "count": 3 },
    { "bucket": "5-10m", "count": 8 },
    { "bucket": "10-15m", "count": 14 },
    { "bucket": "15-30m", "count": 17 },
    { "bucket": "30m+", "count": 6 }
  ],
  "trends": [
    {
      "date": "2025-02-12",
      "calls": 4,
      "avgCloseScore": 78
    }
  ],
  "members": [
    {
      "userId": "usr_a1b2c3d4",
      "name": "Jordan Lee",
      "calls": 12,
      "evaluations": 10,
      "avgCloseScore": 79,
      "avgDurationSeconds": 1760,
      "strengths": 8,
      "weaknesses": 3,
      "risks": 2,
      "avgCoveragePct": 85,
      "personality": "analytical"
    }
  ]
}
{
  "scripts": [
    {
      "id": "script_3c4d5e6f",
      "name": "Enterprise discovery",
      "content": {
        "sections": [],
        "prompts": []
      },
      "is_active": true,
      "updated_at": "2025-02-12T11:00:00.000Z"
    }
  ]
}
{
  "script": {
    "id": "script_3c4d5e6f",
    "name": "Enterprise discovery",
    "content": {
      "sections": [],
      "prompts": []
    },
    "is_active": false,
    "updated_at": "2025-02-12T11:00:00.000Z"
  }
}
{
  "script": {
    "id": "script_3c4d5e6f",
    "name": "Enterprise discovery",
    "content": {
      "sections": [
        {
          "id": "section_discovery",
          "name": "Discovery",
          "type": "script",
          "content": "What is driving this initiative?",
          "next": [],
          "position": {
            "x": 120,
            "y": 80
          }
        }
      ],
      "prompts": [
        {
          "id": "prompt_budget",
          "trigger": "budget",
          "text": "Ask how the buying team evaluates investment.",
          "enabled": true
        }
      ]
    },
    "is_active": true,
    "updated_at": "2025-02-12T11:05:00.000Z"
  }
}
{
  "ok": true
}

Close AI API

Use the Close AI API to manage desktop coaching sessions, generate session analysis, configure prompt presets and analytics settings, manage sales scripts, and retrieve workspace dashboards.

All Close AI endpoints use the authenticated browser Supabase session cookie. They do not use desktop JWT authentication. Send requests to https://app.talkturo.com with the session cookie included.

Endpoint summary

MethodPathPurpose
GET/api/close-ai/sessionsList Close AI sessions
GET/api/close-ai/sessions/{sessionId}Get a session and its related data
PATCH/api/close-ai/sessions/{sessionId}Rename or clear a session title
DELETE/api/close-ai/sessions/{sessionId}Delete a session and related data
POST/api/close-ai/sessions/{sessionId}/analyzeAnalyze a session transcript
GET/api/close-ai/promptsList prompt presets
POST/api/close-ai/promptsCreate a prompt preset
GET/api/close-ai/settingsGet analytics settings
PUT/api/close-ai/settingsUpdate analytics settings
GET/api/close-ai/dashboardGet workspace dashboard metrics
GET/api/close-ai/scriptsList workspace scripts
POST/api/close-ai/scriptsCreate a workspace script
PUT/api/close-ai/scriptsUpdate a workspace script
DELETE/api/close-ai/scriptsDelete a workspace script

Sessions

The sessions endpoints let you find recorded Close AI sessions, retrieve transcripts and analysis, rename sessions, delete sessions, and trigger analysis.

List sessions

GET /api/close-ai/sessions

Use query parameters to paginate results, search session titles, or limit results to a workspace.

Query parameters

query
limitinteger

Maximum number of sessions to return. Values are clamped to the range 1 through 100. Defaults to 50.

Allowed values:1100
query
offsetinteger

Number of sessions to skip before returning results. Defaults to 0.

query
qstring

Case-insensitive substring search against the session title.

query
accountstring

Workspace slug. When provided, the response includes sessions for that workspace and legacy sessions without an account assignment.

Request

curl "https://app.talkturo.com/api/close-ai/sessions?limit=25&offset=0&q=discovery&account=acme-sales" \
  -b "sb-session=authenticated-browser-session"

Response

sessionsarray

Sessions matching the supplied pagination, search, and workspace filters.

sessions[].idstring

Unique session identifier.

sessions[].user_idstring

Identifier of the user who owns the session.

sessions[].account_idstring or null

Workspace identifier. Legacy sessions may have no workspace assignment.

sessions[].titlestring or null

Session title.

sessions[].session_typestring

Type assigned to the session.

sessions[].started_atstring

Session start timestamp.

sessions[].ended_atstring or null

Session end timestamp.

sessions[].statusstring

Current session status.

sessions[].duration_secondsnumber or null

Session duration in seconds.

sessions[].updated_atstring

Timestamp of the most recent session update.

countnumber

Number of sessions returned for the query.

Get a session

GET /api/close-ai/sessions/{sessionId}

path
sessionIdstring
Required

Session identifier.

Request

curl "https://app.talkturo.com/api/close-ai/sessions/sess_7f2c91a4" \
  -b "sb-session=authenticated-browser-session"

Response

sessionobject

Session metadata.

session.idstring

Unique session identifier.

session.user_idstring

Identifier of the session owner.

session.titlestring or null

Session title.

session.session_typestring

Type assigned to the session.

session.started_atstring

Session start timestamp.

session.ended_atstring or null

Session end timestamp.

session.statusstring

Current session status.

session.duration_secondsnumber or null

Session duration in seconds.

session.updated_atstring

Timestamp of the most recent update.

session.created_atstring

Session creation timestamp.

session.parent_session_idstring or null

Identifier of the parent session when this session was created from another session.

transcriptsarray

Transcript segments for the session. Returns an empty array when no transcript exists.

transcripts[].idstring

Transcript segment identifier.

transcripts[].session_idstring

Session identifier associated with the transcript segment.

transcripts[].start_atstring or null

Segment start timestamp.

transcripts[].end_atstring or null

Segment end timestamp.

transcripts[].speakerstring

Speaker label.

transcripts[].textstring

Transcript text.

transcripts[].langstring or null

Transcript language.

transcripts[].created_atstring

Transcript creation timestamp.

messagesarray

AI messages associated with the session. Returns an empty array when no messages exist.

messages[].idstring

Message identifier.

messages[].session_idstring

Session identifier associated with the message.

messages[].sent_atstring

Message timestamp.

messages[].rolestring

Message role.

messages[].contentstring

Message content.

messages[].tokensnumber or null

Token count for the message.

messages[].modelstring or null

Model used to generate the message.

messages[].created_atstring

Message creation timestamp.

summaryobject or null

Generated session summary. Returns null when no summary exists.

summary.session_idstring

Session identifier associated with the summary.

summary.generated_atstring

Summary generation timestamp.

summary.modelstring or null

Model used to generate the summary.

summary.textstring or null

Full summary text.

summary.tldrstring or null

Short summary.

summary.bullet_jsonunknown or null

Structured summary bullets.

summary.action_jsonunknown or null

Structured follow-up actions.

summary.tokens_usednumber or null

Tokens used to generate the summary.

summary.updated_atstring

Timestamp of the most recent summary update.

analysisobject or null

Generated coaching analysis. Returns null when no analysis exists.

analysis.session_idstring

Session identifier associated with the analysis.

analysis.close_scorenumber or null

Overall Close AI score.

analysis.score_breakdownunknown

Score breakdown by evaluation category.

analysis.strengthsunknown

Detected strengths.

analysis.weaknessesunknown

Detected weaknesses.

analysis.risksunknown

Detected risks.

analysis.objectionsunknown

Detected objections.

analysis.questionsunknown

Question analysis.

analysis.personalityunknown

Detected personality information.

analysis.talk_metricsunknown

Conversation and speaking metrics.

analysis.script_coverageunknown

Script coverage metrics.

analysis.languagestring or null

Analysis language.

analysis.modelstring or null

Model used to generate the analysis.

analysis.generated_atstring

Analysis generation timestamp.

Rename a session

PATCH /api/close-ai/sessions/{sessionId}

An empty title clears the existing title.

path
sessionIdstring
Required

Session identifier.

body
titlestring
Required

New session title. Pass an empty string to clear the title.

Request

curl -X PATCH "https://app.talkturo.com/api/close-ai/sessions/sess_7f2c91a4" \
  -H "Content-Type: application/json" \
  -b "sb-session=authenticated-browser-session" \
  -d '{"title":"Northstar discovery call"}'

Response

okboolean

Whether the update succeeded.

titlestring

The updated session title.

Delete a session

DELETE /api/close-ai/sessions/{sessionId}

Deleting a session also removes its transcripts, AI messages, summary, and analysis through the database cascade.

path
sessionIdstring
Required

Session identifier.

Request

curl -X DELETE "https://app.talkturo.com/api/close-ai/sessions/sess_7f2c91a4" \
  -b "sb-session=authenticated-browser-session"

Response

okboolean

Whether the delete request completed without a database error.

deletedboolean

Indicates that the delete operation completed.

Analyze a session

POST /api/close-ai/sessions/{sessionId}/analyze

The session must contain a transcript. The optional workspace slug attributes analysis for legacy sessions.

path
sessionIdstring
Required

Session identifier.

body
accountSlugstring

Workspace slug used for workspace attribution of legacy sessions.

Request

curl -X POST "https://app.talkturo.com/api/close-ai/sessions/sess_7f2c91a4/analyze" \
  -H "Content-Type: application/json" \
  -b "sb-session=authenticated-browser-session" \
  -d '{"accountSlug":"acme-sales"}'

Response

analysisobject

Generated analysis for the session.

analysis.session_idstring

Session identifier.

analysis.close_scorenumber or null

Overall Close AI score.

analysis.score_breakdownunknown

Score by evaluation category.

analysis.strengthsunknown

Detected strengths.

analysis.weaknessesunknown

Detected weaknesses.

analysis.risksunknown

Detected risks.

analysis.objectionsunknown

Detected objections.

analysis.questionsunknown

Question analysis.

analysis.personalityunknown

Detected personality information.

analysis.talk_metricsunknown

Conversation metrics.

analysis.script_coverageunknown

Script coverage metrics.

analysis.languagestring or null

Language used for the analysis.

analysis.modelstring or null

Model used to generate the analysis.

analysis.generated_atstring

Analysis generation timestamp.

Analysis requests can return 401 for an unauthenticated session, 404 when the session does not exist, 422 when the session has no transcript, 502 when analysis generation fails, or 500 when the generated analysis cannot be saved.

Prompts

Prompt presets provide reusable prompts for Close AI analysis.

List prompt presets

GET /api/close-ai/prompts

query
templatesstring

When set to true, returns only template presets.

Allowed values:true

Request

curl "https://app.talkturo.com/api/close-ai/prompts?templates=true" \
  -b "sb-session=authenticated-browser-session"

Response

presetsarray

Prompt presets ordered by default status and update time.

presets[].idstring

Preset identifier.

presets[].user_idstring

Identifier of the preset owner.

presets[].titlestring

Preset title.

presets[].promptstring

Prompt text.

presets[].is_defaultboolean

Whether the preset is the user's default.

presets[].is_templateboolean

Whether the preset is a template.

presets[].created_atstring

Preset creation timestamp.

presets[].updated_atstring

Timestamp of the most recent preset update.

Create a prompt preset

POST /api/close-ai/prompts

body
titlestring
Required

Preset title. Must contain between 1 and 200 characters.

body
promptstring
Required

Prompt text. Must contain between 1 and 20,000 characters.

body
is_defaultboolean

Whether to make this the user's default preset. Defaults to false. Creating a new default clears the user's existing default.

body
is_templateboolean

Whether to mark the preset as a template. Defaults to false.

Request

curl -X POST "https://app.talkturo.com/api/close-ai/prompts" \
  -H "Content-Type: application/json" \
  -b "sb-session=authenticated-browser-session" \
  -d '{
    "title": "Discovery call review",
    "prompt": "Evaluate discovery depth, qualification, and next steps.",
    "is_default": true,
    "is_template": false
  }'

Response

presetobject

The newly created prompt preset.

preset.idstring

Preset identifier.

preset.user_idstring

Identifier of the preset owner.

preset.titlestring

Preset title.

preset.promptstring

Prompt text.

preset.is_defaultboolean

Whether the preset is the user's default.

preset.is_templateboolean

Whether the preset is a template.

preset.created_atstring

Preset creation timestamp.

preset.updated_atstring

Timestamp of the most recent update.

Settings

Settings endpoints store the analytics system prompt used by Close AI.

Get analytics settings

GET /api/close-ai/settings

Request

curl "https://app.talkturo.com/api/close-ai/settings" \
  -b "sb-session=authenticated-browser-session"

Response

analytics_system_promptstring or null

Custom analytics system prompt. Returns null when no custom prompt is configured.

updated_atstring or null

Timestamp of the most recent settings update.

Update analytics settings

PUT /api/close-ai/settings

body
analytics_system_promptstring or null
Required

Analytics system prompt. Pass null to clear the custom prompt. A string cannot exceed 20,000 characters.

Request

curl -X PUT "https://app.talkturo.com/api/close-ai/settings" \
  -H "Content-Type: application/json" \
  -b "sb-session=authenticated-browser-session" \
  -d '{
    "analytics_system_prompt": "Focus on discovery quality and measurable next steps."
  }'

Response

analytics_system_promptstring or null

Saved analytics system prompt.

updated_atstring

Timestamp of the settings update.

Malformed JSON returns invalid_json. Schema validation returns invalid_body, and database upsert failures return save_failed.

Dashboard

The dashboard endpoint returns aggregated workspace metrics for a selected time range.

Get dashboard data

GET /api/close-ai/dashboard

query
daysinteger

Number of days to include. Values are clamped to the range 1 through 365. Defaults to 30.

Allowed values:1365

Request

curl "https://app.talkturo.com/api/close-ai/dashboard?account=acme-sales&days=30" \
  -b "sb-session=authenticated-browser-session"

Response

kpisobject

Workspace-level call, scoring, duration, and membership KPIs.

coachingobject

Aggregated strengths, weaknesses, risks, and evaluation counts.

objectionsobject

Objection totals grouped by category, type, and intensity.

questionsobject

Open, closed, deep, and missed-question metrics.

personalityarray

Counts grouped by detected personality type.

languageobject

Aggregated talk-share, speaking-rate, patience, and monologue metrics.

scriptobject

Script coverage and ordering metrics.

scoresobject

Close score distribution and average score.

durationDistributionarray

Call counts grouped by duration bucket.

trendsarray

Daily call counts and average Close AI scores.

membersarray

Per-member call, evaluation, score, coaching, script, and personality metrics.

The caller must belong to the requested workspace. Requests can return 401 for an unauthenticated session, 400 for a missing account, 404 for an unknown workspace, or 403 when workspace access is denied.

Scripts

Scripts are workspace-level Close AI playbooks. Setting a script as active deactivates the other scripts in the same workspace.

List scripts

GET /api/close-ai/scripts

Request

curl "https://app.talkturo.com/api/close-ai/scripts?account=acme-sales" \
  -b "sb-session=authenticated-browser-session"

Response

scriptsarray

Scripts available in the workspace.

scripts[].idstring

Script identifier.

scripts[].namestring

Script name.

scripts[].contentobject

Script sections and prompts.

scripts[].is_activeboolean

Whether the script is active.

scripts[].updated_atstring

Timestamp of the most recent update.

Create a script

POST /api/close-ai/scripts

body
namestring

Script name. If omitted, empty, or not a string, the route uses Untitled script.

Request

curl -X POST "https://app.talkturo.com/api/close-ai/scripts?account=acme-sales" \
  -H "Content-Type: application/json" \
  -b "sb-session=authenticated-browser-session" \
  -d '{"name":"Enterprise discovery"}'

Response

scriptobject

The newly created script.

script.idstring

Script identifier.

script.namestring

Script name.

script.contentunknown

Script sections and prompts.

script.is_activeboolean

Whether the script is active.

script.updated_atstring

Timestamp of the most recent update.

Update a script

PUT /api/close-ai/scripts

The id field is required. Sections can use the type script or info. When is_active is true, all other scripts in the workspace are deactivated first.

body
idstring
Required

Script identifier.

body
namestring

Updated script name.

body
contentobject

Script content containing sections and prompts. Both arrays default to empty arrays.

body
content.sectionsarray

Script sections. Each section includes an identifier, name, type, content, optional next steps, and optional position.

body
content.sections[].typestring

Section type.

Allowed values:scriptinfo
body
content.sections[].nextarray

Conditional transitions to other sections. Each transition includes an identifier, condition, and nullable target identifier.

body
content.promptsarray

Prompt definitions. Each prompt includes an identifier, trigger, text, and enabled state.

body
is_activeboolean

Whether to activate the script. Activating it deactivates other scripts in the workspace.

Request

curl -X PUT "https://app.talkturo.com/api/close-ai/scripts" \
  -H "Content-Type: application/json" \
  -b "sb-session=authenticated-browser-session" \
  -d '{
    "id": "script_3c4d5e6f",
    "name": "Enterprise discovery",
    "content": {
      "sections": [
        {
          "id": "section_discovery",
          "name": "Discovery",
          "type": "script",
          "content": "What is driving this initiative?",
          "next": [],
          "position": {
            "x": 120,
            "y": 80
          }
        }
      ],
      "prompts": [
        {
          "id": "prompt_budget",
          "trigger": "budget",
          "text": "Ask how the buying team evaluates investment.",
          "enabled": true
        }
      ]
    },
    "is_active": true
  }'

Response

scriptobject

The updated script.

script.idstring

Script identifier.

script.namestring

Script name.

script.contentunknown

Updated sections and prompts.

script.is_activeboolean

Whether the script is active.

script.updated_atstring

Timestamp of the most recent update.

Delete a script

DELETE /api/close-ai/scripts

query
idstring
Required

Script identifier.

Request

curl -X DELETE "https://app.talkturo.com/api/close-ai/scripts?id=script_3c4d5e6f" \
  -b "sb-session=authenticated-browser-session"

Response

okboolean

Whether the delete operation completed successfully.

Script requests require an authenticated browser session. Listing and creating scripts also require the account workspace query parameter. Deleting a script requires the id query parameter.