← All documentationContents ↓

API Reference: Team Agent (Ask Simply)

Drive Ask Simply, the in-app AI agent: manage sessions and messages, approve or reject agent proposals, escalate to human support, and administer knowledge sources.

Overview

Ask Simply is the in-app AI agent built into Simply360. A signed-in user chats with it in a session; each message the user sends starts an agent run in which the agent can call tools from a catalog filtered to that user's permissions. Read-only tools execute directly. Changes are different: instead of writing data on its own, the agent returns a proposal — a structured, risk-labeled description of the change — that the user must explicitly approve before it executes. When the agent cannot help, the user can hand the session off to human support.

The Team Agent API is the surface behind the Ask Simply panel in the webapp and the Simply Anywhere mobile app. It covers three areas:

  • Sessions, messages, and feedback — list, read, and archive sessions; send messages, receive replies, and rate owned assistant messages.
  • Proposals — approve (execute) or reject changes the agent drafted.
  • Human support — check responder availability, create a support handoff, and list a session's handoffs.

Two team-level settings surfaces — knowledge sources and support scope — are privileged administration endpoints.

Authentication and Tiers

Twelve operations are standard tier and four (the /settings endpoints) are privileged. This entire surface is first-party and user-bound: every route requires the TEAM_AGENT_USE or TEAM_ADMIN_AGENT_USE feature permission. Standard operations accept either a signed-in Cognito user token or an OAuth user token issued to the explicitly allowlisted simply-anywhere-ios and simply-anywhere-ios-dev native clients with the identity:read scope. The privileged settings operations remain Cognito-only. Team API keys (s360_live_...), API-key session tokens, and external OAuth clients cannot use this surface. View-level Ask Simply permission allows question-answering, permitted searches, guidance, and feedback on owned assistant messages. Edit-level Ask Simply permission is also required before the runtime exposes or executes draft_* proposal tools; every proposal still re-checks the caller's underlying feature, edit, and data permissions. The examples below use $S360_ACCESS_TOKEN as a placeholder for an accepted first-party user access token; see Authentication.

  • 403 COGNITO_REQUIRED — caller is not an accepted signed-in first-party user.
  • 403 OAUTH_CLIENT_FORBIDDEN or 403 OAUTH_SCOPE_REQUIRED — an OAuth caller is not an allowlisted native client or lacks identity:read.
  • 403 TEAM_AGENT_FEATURE_UNAVAILABLE — the team does not have Ask Simply enabled.
  • 403 TEAM_AGENT_PERMISSION_DENIED — the user lacks Ask Simply permission.
  • 403 TEAM_AGENT_SETTINGS_DENIED — settings endpoints additionally require a Team Admin (or edit-level TEAM_ADMIN_AGENT_USE).

If your integration needs programmatic (API-key or agent-driven) access to Simply360 data, use the standard data endpoints or the hosted MCP Server instead; the Team Agent surface is specifically the product's own assistant.

Endpoints

MethodPathTierPurpose
GET/v1/team-agent/sessionsstandardList the current user's Ask Simply sessions.
GET/v1/team-agent/sessions/{sessionSimplyId}standardGet one session with its messages.
GET/v1/team-agent/runs?idempotencyKey={key}standardDiscover the current user's run created for a send-message request key.
GET/v1/team-agent/runs/{runSimplyId}standardPoll one owned run's accumulated progress and persisted messages.
PUT/v1/team-agent/sessions/{sessionSimplyId}/archivestandardArchive a session.
POST/v1/team-agent/messagesstandardSend a message; starts a new session when none is given.
POST/v1/team-agent/messages/{messageSimplyId}/feedbackstandardCreate or replace the current user's rating for an owned assistant message.
POST/v1/team-agent/proposals/{proposalSimplyId}/approvestandardApprove and execute a proposal.
POST/v1/team-agent/proposals/{proposalSimplyId}/rejectstandardReject a draft proposal.
GET/v1/team-agent/support/availabilitystandardResolve human-support availability for the current user.
POST/v1/team-agent/support/handoffsstandardCreate a support handoff from a session.
GET/v1/team-agent/sessions/{sessionSimplyId}/support-handoffsstandardList a session's support handoffs.
GET/v1/team-agent/settings/knowledge-sourcesprivilegedList the team's Ask Simply knowledge sources.
PUT/v1/team-agent/settings/knowledge-sourcesprivilegedUpdate the team's knowledge sources.
GET/v1/team-agent/settings/support-scopeprivilegedList the local support-agent scope.
PUT/v1/team-agent/settings/support-scopeprivilegedUpdate the local support-agent scope.

Sessions

Sessions belong to the user who created them and have status ACTIVE or ARCHIVED. Listing is paginated (limit 1–100, default 25; offset default 0). The session detail includes the message history; each message carries its role (USER, ASSISTANT, or SYSTEM), content, source references, UI intents, tool calls, proposals, the run's resulting control state, and the current user's nullable feedback.

const sessions = await s360.teamAgent.listSessions({ limit: 25 });

const detail = await s360.teamAgent.getSession('TAGS-1234-ABCD');
console.log(detail.data.session.title, detail.data.session.status);

await s360.teamAgent.archiveSession('TAGS-1234-ABCD');
curl -s "https://api.simply360.app/v1/team-agent/sessions?limit=25" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN"

curl -s -X PUT "https://api.simply360.app/v1/team-agent/sessions/TAGS-1234-ABCD/archive" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN"

Run Discovery and Polling

POST /v1/team-agent/messages persists the turn and returns 202 with status: "RUNNING", a null assistantMessage, and the runSimplyId to poll before the model is invoked by the durable continuation worker. A terminal idempotency replay may instead return 201 with the already-persisted assistant message. A client should generate one idempotencyKey per user send and may begin run discovery while that POST is pending. GET /v1/team-agent/runs?idempotencyKey=... returns 404 TEAM_AGENT_RUN_NOT_FOUND during the short interval before the run row is visible; keep polling with bounded backoff. Once either the POST or discovery returns a runSimplyId, poll GET /v1/team-agent/runs/{runSimplyId} until terminal. Both run lookups are scoped to the current team and creating user, and use the same response shape.

const idempotencyKey = crypto.randomUUID();
const post = s360.teamAgent.sendMessage({
  message: 'How many wizard submissions came in this week?',
  idempotencyKey,
});

// In a real client, retry discovery on its initial bounded 404 window while `post` is pending.
const discovered = await s360.teamAgent.findRunByIdempotencyKey(idempotencyKey);
const run = await s360.teamAgent.getRun(discovered.data.runSimplyId);
console.log(run.data.status, run.data.runtimeEvents);

const reply = await post;
if (reply.data.status === 'RUNNING') {
  // Poll getRun(reply.data.runSimplyId) until terminal, then render its assistantMessage.
} else {
  console.log(reply.data.assistantMessage.content);
}

The run response envelope's data contains runSimplyId, sessionSimplyId, status, startedAt, nullable completedAt, nullable safe error, ordered accumulated runtimeEvents, the persisted userMessage, nullable assistantMessage, and controlState. Event payloads and errors are redacted for the public boundary; diagnostic payloads, raw provider errors, prompts, and internal numeric IDs are never returned.

StatusClient behavior
RUNNINGContinue polling. New runtime events accumulate in sequence order.
WAITINGStop polling and render the persisted assistant message plus its resumable control state, such as clarification or proposal approval.
COMPLETEDStop polling and replace progress UI with the persisted assistant message.
FAILEDStop polling and show error.userVisibleSummary. Do not display or infer a raw provider error.
CANCELLEDStop polling. The run will not produce additional work.

If the original POST times out or loses its connection, do not create a new request key. Discover the run first. If no run becomes visible after a bounded discovery window, retry the same POST body with the same key: a running run returns the canonical 202 RUNNING response, a completed or waiting run replays its persisted 201 response without duplicate model spend, and a failed run returns its persisted safe failure as a 409. To intentionally try again after a failure, let the user edit or confirm the message and send it with a new key.

Send a Message

Send the user's message and receive either the terminal reply or a pollable background handoff in the same call. Omit sessionSimplyId to start a new session; include it to continue an existing one. The optional contextSnapshot tells the agent what the user is currently looking at (route, page title, selected records or resource, active filters) so answers can be grounded in the current screen. View Studio, Automation Builder, Outgoing Message Studio, and Document Studio contribute strict versioned context contracts through the Ask Simply rail. Each contract reports only bounded, sanitized builder state and derives canEdit from current feature-edit permission; route queries, document/message content, recipient details, credentials, and internal numeric IDs are excluded. Pass a client-generated idempotencyKey (normally a UUID, at most 64 characters) so discovery and retries refer to the same logical send without creating a duplicate run or duplicate model spend.

Exact “how many” questions use the permission-aware count_data_records read tool, which applies metadata or readable custom-field filters in one Collection and returns the exact matching total with a bounded metadata-only evidence page. Natural-language search_team_records remains a relevance-oriented discovery tool and is never treated as exhaustive. For questions that cross linked Collections, Ask Simply first resolves the related public record Simply IDs and then uses the bounded in relationship filter. It must not add separate batch counts when a target record could link to more than one batch; if the complete relationship filter exceeds the bound and uniqueness is not guaranteed, it reports that the exact total could not be established. When the schema exposes lifecycle fields, wording such as “purchased,” “paid,” or “completed” must be matched to a confirmed stored status so requested, failed, unpaid, draft, or abandoned records are not counted.

TypeScript SDK

const reply = await s360.teamAgent.sendMessage({
  message: 'Archive the duplicate contact record for Dana Wells.',
  idempotencyKey: crypto.randomUUID(), // retry-safe: a repeat with the same key replays the original run
  // sessionSimplyId omitted: starts a new session
});

if (reply.data.status === 'RUNNING') {
  let run = await s360.teamAgent.getRun(reply.data.runSimplyId);
  while (run.data.status === 'RUNNING') {
    await new Promise((resolve) => setTimeout(resolve, 1500));
    run = await s360.teamAgent.getRun(reply.data.runSimplyId);
  }
  console.log(run.data.assistantMessage?.content);
} else {
  console.log(reply.data.assistantMessage.content);
  console.log(reply.data.controlState?.stateType); // e.g. AWAITING_PROPOSAL_APPROVAL
}

cURL

curl -s -X POST "https://api.simply360.app/v1/team-agent/messages" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionSimplyId": "TAGS-1234-ABCD",
    "message": "How many wizard submissions came in this week?"
  }'

The 201 terminal replay and 202 running response envelopes contain:

FieldDescription
sessionThe session (created or continued).
userMessageThe stored user message.
assistantMessageThe non-null persisted reply for a 201 terminal replay; exactly null for a 202 RUNNING handoff.
runSimplyIdIdentifier of the agent run that produced the reply or should be polled after a handoff.
statusCOMPLETED or WAITING for 201; RUNNING for 202.
availableToolsNames of the tools available to this user in this run (permission-filtered).
controlStateWhat the conversation is waiting on, if anything (see below).
runtimePrompt/context-builder/redaction/control-flow version stamps for the run.

The controlState.stateType values are READY, AWAITING_PROPOSAL_APPROVAL, AWAITING_CLARIFICATION, BACKGROUND_TASK_PENDING, SUPPORT_HANDOFF_AVAILABLE, and FAILED. When the state is AWAITING_PROPOSAL_APPROVAL, controlState.pendingProposalSimplyIds lists the proposals waiting on the user.

Message Feedback

Rate an owned assistant message with UP or DOWN and an optional comment of at most 1,000 characters. The first request creates the current user's feedback row and returns 201; later requests replace its rating and comment and return 200. Omitting comment, passing null, or passing blank text clears the previous comment. The feedback row keeps the same simplyId across updates.

const result = await s360.teamAgent.submitMessageFeedback('AGMS-1234-ABCD', {
  rating: 'DOWN',
  comment: 'The answer cited an outdated policy.',
});

console.log(result.data.created, result.data.feedback.rating);
curl -s -X POST "https://api.simply360.app/v1/team-agent/messages/AGMS-1234-ABCD/feedback" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "rating": "DOWN", "comment": "The answer cited an outdated policy." }'

Only the user who owns the message's session, in the same team, can rate it or read the resulting feedback. User-authored messages, another user's or team's messages, deleted sessions, and unknown messages all return the same 404 TEAM_AGENT_MESSAGE_NOT_FOUND response. Session and run responses expose only the current user's feedback; they never expose another user's row or internal numeric IDs.

UI Intents

Assistant messages can include uiIntents: small, client-renderable actions that point back to Simply360 surfaces the user is allowed to open. Read tool results derive OPEN_RECORD, OPEN_DATA_VIEW, OPEN_DATA_CARD, OPEN_TEAM_WORKSPACE, and OPEN_ADMIN_BUILDER intents from their source references when a canonical route exists. Builder intents remain permission-scoped; for Collection-level shortcuts the server chooses a section the caller can actually access, such as Settings, Schema, Layout, Views, Permissions, or Duplicate Detection.

PREFILL_SUPPORTED_BUILDER is a web-only handoff for an unsaved builder draft. The first supported persistence-free target is Outgoing Message Studio. Its strict version-1 builderPrefill contains details, content, and an optional schedule, but never recipients or resolved audience data. The webapp places the payload in tab-scoped storage under a cryptographically random, five-minute, single-use nonce; only that nonce enters the route query, and the builder deletes it before parsing. A dirty builder asks before replacement. Nothing is persisted until the user performs the builder's normal save action. View-prefill remains a typed contract but is not exposed as a tool because the current View Studio cannot host a new unsaved View without first creating a row.

Web clients should render intents with a routeName as navigation actions using the supplied public *SimplyId route params. Simply Anywhere opens record intents natively; View, Card, Workspace, admin-builder, and prefill intents are rendered as web-only actions until equivalent native surfaces exist. UI intents do not execute writes and are billing-neutral.

Proposals

Tools that change data are draft-first: the run records a proposal instead of executing immediately. A proposal describes the tool to run, its (redacted) arguments, a normalized before/after diff, the affected resources, a risk level (LOW, MEDIUM, HIGH), and permission and validation summaries. Proposals expire (expiresAt) if not acted on.

Proposal statuses: DRAFTAPPROVEDEXECUTINGEXECUTED, or REJECTED, EXPIRED, FAILED.

Bulk Record Update Proposals

With edit-level Ask Simply access and update permission for the Collection and requested fields, Ask Simply can draft draft_bulk_update_data_records. The tool accepts one Collection, an exact set of 1–50 unique active record Simply IDs, and one shared field-change object keyed only by public field Simply IDs. Ask Simply must read the current Collection schema and resolve the record set before drafting. It must not infer a similarly named field, and a null value clears only the exact field the user explicitly requested. Requests over 50 records are split into separately reviewable proposals. Collections with Approval Workflows enabled use the normal record edit and approval flow instead, because their approval-state transitions cannot be combined with this proposal's all-or-nothing transaction.

The server preflights every record and field and creates a HIGH-risk proposal showing the affected-record count, field-assignment count, exact field labels with public Simply IDs and values, up to five record-name and public-ID samples, and the estimated direct platform charge. Direct record edits are billing-neutral, so that estimate is $0.00; normal Ask Simply AI usage metering still applies. A server-only fingerprint binds the reviewed Collection/field schema without exposing physical table or column metadata through TeamAgent API/client projections. Approval rechecks Ask Simply edit access, Collection read/update and field update permissions, active membership, that schema fingerprint, field existence, and the update timestamp captured for every record. It then calls the canonical bulk record service in one transaction while holding row locks. If any record or schema changed, any permission or membership is no longer valid, or any write fails, the whole proposal fails and no record changes are committed.

This adds no new Public API, SDK, OpenAPI, or hosted MCP operation. Web and Simply Anywhere display the bulk review and approve/reject it through the existing generic Team Agent proposal contract.

Blueprint, Export, Notification, Commerce, and Domain Proposals

The following integrations use the same proposal spine and re-run current authorization and canonical validation at approval:

  • Blueprint install and upgrade: high-risk proposals carry only public Blueprint, version, integration, mapping, and target identifiers. Approval uses the shared queue dispatcher and remains EXECUTING while the owned Background Task runs. The worker rechecks publication, version lineage, integrations, mappings, target eligibility, and permissions before applying the manifest.
  • CSV export: draft_export_records accepts exactly one Collection or View Simply ID, explicit readable DataField Simply IDs, safe system columns, an optional canonical filter, and optional record Simply IDs. A View's saved filter, the request filter, and selection are conjunctive. Read-only approval workflows export approved snapshots; current access and the frozen scope fingerprint are revalidated in the worker and again before issuing the requesting user's short-lived Background Task download. The worker uses stable keyset pagination, bounded multipart upload, formula-safe CSV values, retry/DLQ handling, and a deterministic header-only file for zero rows.
  • Teammate notification: draft_notify_team_user is Team Admin-only and creates one exact durable in-app notification about a record, conversation, or report. Both the approver and active recipient must still be able to read the linked resource. The server owns the deep link, allocates an idempotent notification Simply ID with the proposal, attempts realtime inbox fan-out, and sends no native push, email, or SMS. list_my_notifications reads only the current member's inbox without changing read state.
  • Commerce configuration: high-risk fee, surcharge, code, and cart-recovery proposals show the complete flattened financial/configuration values and execute through the canonical services with a locked reviewed-state comparison. Cart recovery accepts only DISABLED and MANUAL_ONLY. Refunds, charges, payment accounts, payment methods, and transactions remain explain-only.
  • Website custom domain: get_website_custom_domain_status is a pure stored-state read. Setting, changing, clearing, and explicitly verifying a domain are high-risk proposals that use the canonical Website service, preserve crash-retry cleanup state, and keep certificate ARNs and CloudFront distribution IDs out of Team Agent output. DNS for outgoing-email sender verification remains explain-only.

Completed export files are delivered only through the requesting member's owned Background Task result. Web and Simply Anywhere use GET /v1/background-tasks/{backgroundTaskSimplyId}/result-download to obtain a short-lived URL after the task is complete; neither surface accepts a bucket or object key from the caller.

Outgoing Message Proposals

When the caller has outgoing email or SMS send permission, Ask Simply can draft outbound sends with draft_send_outgoing_message and draft_send_outgoing_message_from_template. These are approval-only DRAFT tools: the model never supplies raw recipient email addresses or phone numbers and never transmits messages directly. It supplies a server-resolved recipient specification such as a Collection, View, canonical dataFilterState, explicit record simplyIds, and the email or phone field simplyId. The server re-checks feature, edit, and data permissions, resolves readable recipient records and their contact field values, and stores a review snapshot in proposal.redactedArguments.resolvedOutgoingMessageReview.

Clients should render that review snapshot before approval: channel, sender, recipient count, recipient samples, scheduled time, subject when applicable, SMS segment details when applicable, and the full message body. Approval re-resolves the recipient specification and queues an OutgoingMessage through the same scheduler-backed outgoing-message pipeline used by the admin studio; it does not bypass suppression, dev-environment interception, sender compliance, prepaid SMS caps, Twilio status handling, or usage accounting. Sends over the default 500-recipient self-approval cap require a Team Admin to approve.

Record Approval Proposals

When the caller has data-agent edit access plus APPROVE_DATA_RECORDS for a Collection, Ask Simply can draft draft_resolve_record_approval for one pending Approval Workflow record. The proposal stores resolvedRecordApprovalReview with the decision, optional reviewer note, record and Collection labels, current approval status, and readable field-level changes.

Clients should render that review snapshot before approval. Approval re-resolves the record, requires it to still be PENDING_REVIEW, re-checks approval permission, and delegates to the same bulk approval service used by the record approval UI. Ask Simply does not write approval status or approved snapshots through a separate code path.

Automation Lifecycle Tools

Users with Automation administration access can ask Ask Simply to troubleshoot and operate Automations. The read tools list_automation_runs and get_automation_run expose the same execution-log concepts as the Automation UI: run status, start/completion time, processed and failed record counts, duration, and whether error details exist. Single-run reads include redacted trigger context and error details so support-style questions like “why didn't this automation fire?” can be answered without exposing internal numeric IDs or secret-shaped values.

draft_set_automation_enabled is the narrow proposal tool for enabling or disabling one Automation. Approval re-checks the Automation by public automationSimplyId, rejects no-op toggles, and updates the existing Automation row through the same schema-drift/snapshot path as other Automation edits. The toggle itself is not billable, but enabling an Automation can cause future configured actions, such as messages, document generation, payments, or AI work, to create usage through their normal billing paths when the Automation later runs.

Conversation Inbox Tools

When the caller has conversation inbox view permission, Ask Simply can read support inbox conversations with list_data_conversations and get_data_conversation. DATA_CONVERSATION_INBOX_VIEW_ALL (or Team Admin status) can read the full team inbox. Plain DATA_CONVERSATION_INBOX_VIEW is scoped to conversations assigned to the current Team User plus unassigned conversations. The read results expose public conversation and message Simply IDs, status, assignment, snooze/SLA state, visitor/requester context, linked record context, and message text; they do not expose internal numeric IDs or provider delivery payloads.

Conversation inbox changes are draft-first. draft_reply_to_conversation, draft_resolve_conversation, and draft_snooze_conversation require edit-level DATA_CONVERSATION_INBOX_RESPOND. draft_assign_conversation requires edit-level DATA_CONVERSATION_INBOX_ASSIGN. Draft validation rejects no-op assignment and resolution proposals, validates snooze dates (future, maximum 30 days), and verifies that assignment targets are active conversation responders.

Approval executes through the existing authenticated conversation inbox router as the approving Team User. Replies use the same inbox message path as the web/mobile inbox, so normal delivery, realtime publishing, message counters, and channel behavior are inherited. Assignment, resolution, and snooze proposals likewise reuse the existing inbox update/snooze paths. Reading and drafting inbox proposals is billing-neutral; approved replies can trigger normal outbound channel delivery costs, such as SMS, according to the existing conversation delivery path.

Duplicate Cleanup Proposals

When the caller has Data Cleanup edit access for a Collection, Ask Simply can draft duplicate-review cleanup actions. draft_merge_duplicate_records is a high-risk proposal that requires both ALLOW_UPDATE and DELETE_DATA_RECORDS data permission for the Collection. draft_dismiss_duplicate_review_item is a low-risk proposal that requires ALLOW_UPDATE. Both tools operate on one pending duplicate review item at a time and reject stale or already-resolved review items.

Merge proposals are server-previewed through the canonical duplicate-merge planner before the user sees them. The proposal card shows the survivor record, merged record, merge readiness, field outcome, reference impact, and whether approval will run synchronously or queue a background duplicate-merge task. Approval re-checks the Collection, review-item status, data permissions, and canonical preview. If the planner classifies the item as ready, approval either calls the same synchronous duplicate-merge executor used by the cleanup UI or queues the existing duplicate-merge worker for background execution; Ask Simply does not implement a separate merge algorithm.

Dismiss proposals mark the duplicate review item as NOT_DUPLICATE and do not merge, archive, or edit either record. Duplicate cleanup reads, drafts, approvals, and dismissals are billing-neutral; they add no pricing catalog entries, invoice lines, prepaid-credit behavior, or usage metering bypass.

// Approve: executes the proposed change and returns the proposal with its executionResult
const approved = await s360.teamAgent.approveProposal('TAGP-1234-ABCD');
console.log(approved.data.status); // EXECUTED (or FAILED)

// Reject: closes the draft with an optional reason
await s360.teamAgent.rejectProposal('TAGP-5678-EFGH', { reason: 'Wrong record selected' });
curl -s -X POST "https://api.simply360.app/v1/team-agent/proposals/TAGP-1234-ABCD/approve" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN"

curl -s -X POST "https://api.simply360.app/v1/team-agent/proposals/TAGP-5678-EFGH/reject" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Wrong record selected" }'

Human Support Handoffs

When the agent cannot resolve something, the user can escalate the session to people. First resolve availability, then create a handoff. The responder pool is either the team's own configured support agents (CUSTOMER_TEAM) or Simply360 internal support (SIMPLY360_INTERNAL), depending on team configuration.

const availability = await s360.teamAgent.getSupportAvailability();
// { state: 'ONLINE' | 'OFFLINE' | 'UNAVAILABLE', canWaitForHuman, canLeaveMessage,
//   providerKind, eligibleResponderCount, availableResponderCount, reason,
//   handoffDisclosure: { requesterEmail }, ... }

if (availability.data.state !== 'UNAVAILABLE') {
  const handoff = await s360.teamAgent.createSupportHandoff({
    sessionSimplyId: 'TAGS-1234-ABCD',
    handoffMode: availability.data.canWaitForHuman ? 'WAIT_FOR_HUMAN' : 'LEAVE_MESSAGE',
    message: 'I need help fixing a broken automation.',
  });
  console.log(handoff.data.dataConversationSimplyId);
}
curl -s "https://api.simply360.app/v1/team-agent/support/availability" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN"

curl -s -X POST "https://api.simply360.app/v1/team-agent/support/handoffs" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionSimplyId": "TAGS-1234-ABCD",
    "handoffMode": "WAIT_FOR_HUMAN",
    "message": "I need help fixing a broken automation."
  }'

The availability response includes handoffDisclosure.requesterEmail so clients can show what identity information will be shared before the user creates a handoff; clients should pair it with the current Ask Simply session title. Creating a handoff opens a support conversation (a DataConversation) linked to the Ask Simply session and returns 201 with the link: dataConversationSimplyId, provider team and kind, the handoff mode (WAIT_FOR_HUMAN or LEAVE_MESSAGE), and its status (REQUESTED, CONNECTED, MESSAGE_LEFT, or CLOSED). If no responder route exists, the API returns 409 SUPPORT_UNAVAILABLE; the requested mode must also be one the availability response allows. Use GET /v1/team-agent/sessions/{sessionSimplyId}/support-handoffs to list a session's handoffs, and the Conversations surface to follow the resulting conversation.

Knowledge Sources (Privileged)

Team Admins choose which knowledge-base article collections Ask Simply may draw answers from. Each source reports its collection, label, kind (KNOWLEDGE_BASE_ARTICLE_COLLECTION), enablement, article count, and any status filter or record filter applied to it.

const sources = await s360.teamAgent.listKnowledgeSources();

await s360.teamAgent.updateKnowledgeSources({
  dataCollectionSimplyIds: ['DCL1-2345-6789', 'DCL9-8765-4321'],
  sourceFilters: [
    { dataCollectionSimplyId: 'DCL1-2345-6789', dataFilterState: null },
  ],
});
curl -s -X PUT "https://api.simply360.app/v1/team-agent/settings/knowledge-sources" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "dataCollectionSimplyIds": ["DCL1-2345-6789", "DCL9-8765-4321"] }'

dataCollectionSimplyIds is the complete enabled set — collections omitted from the array are disabled. sourceFilters optionally narrows a source to matching records via a dataFilterState.

Knowledge search uses semantic embeddings of one canonical article profile: a Title, optional Summary, and Body on one physical table. The selected Collection is always the membership boundary. If a selected child or SMART Collection inherits its article fields, Ask Simply may read the canonical fields from one ancestor source table, but only records with active membership in the selected Collection are eligible. Every configured record filter must resolve entirely to either that membership table or the canonical source table; mixed-table, intermediate-ancestor, and implicit cross-hierarchy keyword filters are rejected. A configured status filter requires exactly one canonical Status reference field and compares exact status labels. Titan receives the first 8,000 characters of the whitespace-normalized canonical text; the freshness hash still covers all sanitized canonical content, but facts beyond that single-vector input cap do not affect semantic ranking.

The complete enabled set may contain at most 2,000 active record memberships in aggregate. The limit is checked again before every search and every indexing page, so growth after enablement fails closed before vector loading or embedding spend. Enabling a source durably queues indexing, and later record changes, membership changes, restores, and deletions reconcile the affected vectors. SMART-filter, direct-membership, full-resync, and reverse-reference changes have the same lifecycle coverage; the first page of a full sweep also repairs orphan vectors left by any missed notification. Search considers the complete bounded eligible set. It returns a temporary indexing error instead of partial results if an eligible vector is missing, stale, corrupt, from a different profile, has the wrong dimensions, or no longer matches the current article content. An embedding timestamp equal to the record timestamp is stale; publication waits for a strictly later database timestamp while holding the record/source lock.

Knowledge sources are intentionally team-wide after Team Admin curation; per-user Collection and field data permissions do not filter these excerpts. Results do not include record-open links. Only the canonical article fields and an optional status are read; record calculated names are never used as article fallback content, an empty canonical title gets a fixed generic label, and returned Collection/status labels are sanitized. Credential-like fields and values are removed before hashing, embedding, or excerpt output. Query and document embedding calls are attributed to TeamAgent tool execution and do not report success until the AI usage log and its cost event commit atomically. Background indexing observes the team's TeamAgent AI spend allowance and purchased credits.

Support Scope (Privileged)

Simply Action Tags Product Boundary

TeamAgent resolves the Action Tags product mode from server-authoritative subscription evidence. For a standalone SIMPLY_ACTION_TAGS Team it may return safe URL-only Action context, but it redacts linked record, Wizard, Fresh Scan, and powered-workflow details and rejects proposals that would create those connections. A broad role, System Admin session, direct URL, or standalone paid Action Tags band does not widen the product.

For a Team with an eligible paid Simply360/AppBrand base contract, the existing Action read/proposal behavior remains available under TEAM_ADMIN_SIMPLY_TAGS. TeamAgent does not change Action Tags plans, collect payment methods, apply retention selections, import CSV, manage custom domains, reveal webhook secrets, issue bearer credentials, or present credentials. Those operations stay on their customer-confirmed first-party UI or documented API boundary.

The support scope defines which local team users and roles act as human support responders for CUSTOMER_TEAM handoffs. Entries are user-based (scopeType: "USER") or role-based (scopeType: "ROLE") and include a live conversationStatus (available or offline) for user entries.

const scope = await s360.teamAgent.listSupportScope();

await s360.teamAgent.updateSupportScope({
  teamUserLinkSimplyIds: ['TUL1-1111-AAAA'],
  teamRoleSimplyIds: ['TRLE-2222-BBBB'],
});
curl -s -X PUT "https://api.simply360.app/v1/team-agent/settings/support-scope" \
  -H "Authorization: Bearer $S360_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "teamUserLinkSimplyIds": ["TUL1-1111-AAAA"], "teamRoleSimplyIds": ["TRLE-2222-BBBB"] }'

Usage Notes

  • The agent's tool catalog is recomputed per request from the caller's feature and data permissions — the agent can never read or change anything the signed-in user could not.
  • Tool call records in messages expose redacted inputs and output summaries, plus a category (READ, DRAFT, EXECUTE, UI_INTENT) and risk level.
  • All identifiers at this boundary are public simplyIds; payload keys carrying numeric database IDs are rejected with a validation error.
  • POST /v1/team-agent/messages returns a 202 RUNNING handoff for a new run so every client follows the durable worker through the run endpoint. A 201 terminal response is reserved for replaying an already-persisted idempotent result. Failures before queue ownership transfers surface through the POST; worker failures persist a safe FAILED run status for pollers.
  • Questions or feedback about this surface? Use the feedback page or email developers@simply360.app.