Tough Customer

Tough Customer workspace API

Every tool the MCP connector exposes, callable over plain HTTPS with a workspace API key — for scripts, back-office jobs and partners that cannot run an OAuth flow.

Authentication

A workspace admin mints an API key under Integrations → REST API. The key is shown exactly once (only its hash is stored). Send it on every request as a bearer token:

Authorization: Bearer tc_…

A key acts as the admin who minted it — including their Salesforce connection — and reaches exactly the tools that admin sees. If that admin is demoted to member, the key keeps working for member tools only; if they leave the workspace, the key is revoked automatically. Keys belong to one workspace: the {orgId} in the URL must be that workspace's id (the same id as the workspace's MCP URL, shown next to the endpoint on the keys page). Never put a key in a URL — it is refused there, and URLs get logged along the way. Rotate by minting a new key and revoking the old one.

Endpoints

Two routes, both under your workspace's endpoint:

GET  https://app.toughcustomer.ai/api/v1/{orgId}/tools            # the catalog this key may call
POST https://app.toughcustomer.ai/api/v1/{orgId}/tools/{tool}     # run one tool; the JSON body is its arguments

List your scenarios:

curl -s -X POST https://app.toughcustomer.ai/api/v1/{orgId}/tools/list_scenarios \
  -H "Authorization: Bearer tc_…" \
  -H "Content-Type: application/json" \
  -d '{}'

A successful call returns the tool's output decoded as JSON:

{ "ok": true, "tool": "list_scenarios", "result": [ { "id": 42, "name": "Pricing objection", "category": "Roleplay" } ] }

Arguments are validated against the tool's schema before it runs — the same JSON schema MCP clients see in tools/list, and the same schema the catalog returns as inputSchema. Tools without required arguments accept an empty body. Bodies are limited to 2 MiB and must be application/json. Every response is Cache-Control: no-store and carries an X-Request-Id to quote to support.

Errors

Every error is one JSON envelope:

{ "ok": false, "error": "<code>", "message": "…" }
errorHTTPMeaning
unauthorized401Missing, malformed, unknown, revoked or expired key — or the key's owner left the workspace.
not_found404The key does not belong to the workspace in the URL, the workspace id is unknown, or the tool does not exist (one constant body for all three).
forbidden403An admin-only tool called with a key whose owner is not (or no longer) a workspace admin.
conflict409The tool reports a conflict (for example a duplicate).
invalid_json400The body is not a JSON object.
invalid_arguments400The body does not match the tool's schema — issues[] lists each violation with its path.
unsupported_media_type415A body without Content-Type: application/json.
payload_too_large413The body is over 2 MiB.
tool_error422The tool refused the call; message is the tool's own text (for example a session id from another workspace).
rate_limited429The key's per-minute limit is exceeded — see Rate limits.
internal500An unexpected failure; message carries a reference id for support.

A 401 carries WWW-Authenticate: Bearer. A 404 is deliberately the same body whether the workspace id, the key's workspace or the tool name is wrong.

Rate limits

Each key may make 60 calls per minute (catalog reads and tool calls alike), counted in a fixed calendar-minute window. Every authenticated response carries X-RateLimit-Limit and X-RateLimit-Remaining; over the limit you get 429 rate_limited with Retry-After (seconds) and retryAfterSeconds in the body. Calls resume in the next minute. Need more? Ask support@toughcustomer.ai.

Tools

Every key reaches the member tools; behavior labels come from the same certification the server publishes to MCP clients as tool annotations. Salesforce-backed tools run on the key owner's Salesforce connection.

ToolCallBehaviorWhat it does
List AI-buyer simulations
list_simulations
POST …/tools/list_simulationsread-onlyList the org's saved AI-buyer simulations.
Create AI buyer from URL
create_simulation
POST …/tools/create_simulationwriteGenerate a new AI buyer persona from a company URL.
Start roleplay session
create_roleplay_session
POST …/tools/create_roleplay_sessionwriteStart a voice roleplay session for a scenario.
Get session score
get_session_score
POST …/tools/get_session_scoreread-onlyFetch the score + coaching for a completed roleplay session.
List scenarios
list_scenarios
POST …/tools/list_scenariosread-onlyList the org's practice scenarios.
List AI voices
list_voices
POST …/tools/list_voicesread-onlyList the available AI-buyer voices.
My assigned learning
tough_learning
POST …/tools/tough_learningread-onlyOpen the learning dashboard — assigned journeys + progress.
Connect Salesforce
connect_salesforce
POST …/tools/connect_salesforceread-onlyAuthorize Salesforce for your user (per-user OAuth).
Disconnect Salesforce
disconnect_salesforce
POST …/tools/disconnect_salesforcewrite (destructive)Revoke your Salesforce authorization.
List Salesforce opportunities
list_opportunities
POST …/tools/list_opportunities
owner's Salesforce
read-onlyList your Salesforce opportunities.
Get opportunity contacts
get_opportunity_contacts
POST …/tools/get_opportunity_contacts
owner's Salesforce
read-onlyList the contacts on a Salesforce opportunity.
Get deal-coaching context
get_coach_context
POST …/tools/get_coach_context
owner's Salesforce
read-onlyPull deal-coaching context for a Salesforce opportunity.
Save roleplay scenario
create_roleplay
POST …/tools/create_roleplaywriteSave a reusable, team-wide roleplay scenario.

Admin tools

Available while the key's owner is a workspace admin — analytics export, scenario and rubric authoring, and member invitations. With a demoted owner these answer 403.

ToolCallBehaviorWhat it does
Export session analytics
export_session_analytics
POST …/tools/export_session_analyticsread-onlyExport org-wide session analytics (rows + summary).
Analytics HTML report
analytics_report_html
POST …/tools/analytics_report_htmlread-onlyGenerate a self-contained HTML analytics dashboard.
Invite teammate
invite_user
POST …/tools/invite_userwriteADMIN ONLY. Invite a teammate by email with a workspace permission + profile fields (T98).
Create scenario
create_scenario
POST …/tools/create_scenariowriteCreate a scenario in any creatable category (full editable field set).
Get scenario
get_scenario
POST …/tools/get_scenarioread-onlyRead one scenario's full editable fields by id.
Update scenario
update_scenario
POST …/tools/update_scenariowrite (destructive)Partially update a scenario — body, scoring prompt, any editable field.
Delete scenario
delete_scenario
POST …/tools/delete_scenariowrite (destructive)Delete a scenario from the org catalog (confirm required).
Create competencies
create_competencies
POST …/tools/create_competencieswriteBulk-insert a competency record set under one category (deduped).
Update competencies
update_competencies
POST …/tools/update_competencieswrite (destructive)Edit/add/delete competencies in one category + subcategory group.
List competencies
list_competencies
POST …/tools/list_competenciesread-onlyThe org rubric grouped category → subcategory → items.

Workspace custom tools

Custom tools authored under Integrations → Custom tools (Salesforce GraphQL, HTTP APIs, Claude agents) are per-workspace, so they are not in the OpenAPI document: read them from your workspace's catalog (GET …/tools, entries with kind: "workspace") and call them by name exactly like a built-in tool.

OpenAPI

The machine-readable specification is generated from the same tool definitions as this page and the MCP server, so it cannot drift from the live API:

https://app.toughcustomer.ai/api/v1/openapi.json

OpenAPI 3.1, bearer security scheme, one operation per built-in tool with its request schema, and the error envelope above. Import it into Postman, Bruno, Swagger UI or your code generator; the document is public and CORS-open. An in-page API explorer is coming with the user-registration endpoint.

Data handling

Calls read and write only the key's workspace, attributed to the key's owner and to the key itself in the workspace's usage ledger. Unexpected errors return a reference id instead of internal details. See the Privacy Policy for what we store and how AI providers process session content, and the Terms of Service for acceptable use. Prefer an OAuth sign-in for a person's own use? That is the MCP connector.