Team API
Manage team roles, permissions, teams, invitations and goal plans, and read live activity counts and team analytics through the Goliath developer API
About
Operations for the people side of your organization: list teammates, manage team invitations, change roles or suspend and restore members, read live activity counts and team performance analytics, and manage the key owner’s own profile.
All operations go through the developer API gateway — one endpoint, called by
operationId. If you haven’t set up a key yet, start with the
Developer API Overview.
Operations
Teammates and profile (READ + WRITE scopes)
| operationId | Scope | What it does |
|---|---|---|
listTeammates |
READ |
Fuzzy-search active teammates by name, email, or phone. limit defaults to 20 and is capped at 50; there is no pagination and suspended members are excluded. Use the returned userId with assignContact and other operations. |
listTeamMembers |
READ |
Page the organization’s roster, including suspended members, with offset and limit (default 50, max 100). Returns identity, organizationRole, organizationMembershipStatus, and createdAt. Keep paging until a short page arrives; filter status to ACTIVE before reporting current members. |
getTeammatesByIds |
READ |
Resolve known teammate user ids to id, firstName, lastName, and email. Pass userIds; foreign-organization ids are rejected. |
getMyProfile |
READ |
Read the key owner’s identity, profile picture, organization role and membership status, personal and resolved timezones, and organization details. |
updateMyProfile |
WRITE |
Update the key owner’s profile. firstName, lastName, and phoneNumber are required together; an empty phone clears it. Optional profilePictureUrl and howDidYouHearAboutUs are partial updates. Email is not editable. See the Account API. |
listTeamMembers.searchTerm matches name/email substrings, a UUID, or a
complete US phone number. Partial phone numbers do not search the phone field.
Without a search term, the newest members come first. Roles are ADMIN and
MEMBER; status is ACTIVE or SUSPENDED.
The roster does not expose other members’ capability grants. Read the key
owner’s own grants with getMyCapabilities.
Live activity counts (READ scope)
| operationId | What it does |
|---|---|
countOutboundTexts |
Count outbound texts created in a time window. Returns total, byUser, and, for an organization-wide read, otherSenders for AI employees and workflows. sent counts accepted dispatches (PENDING, SENT, DELIVERED); delivered is the carrier-confirmed subset, and failed counts FAILED. Skipped sends and inbound texts are excluded. |
getMemberActivity |
What one person did in an exact window, in one read: their own texts and calls (the member’s row from the two reads above), emailsSent (outbound mailbox mail; workflow and AI-employee mail excluded), notesWritten, tasksCreated, appointmentsBooked, tasksCompleted, and dealStageMoves made by hand. Counts only. Omit userId for the key owner; naming a teammate needs VIEW_ALL_PHONES. |
getTeamCallStats |
Read per-member outboundCalls, inboundCalls, connectedCalls, conversationCalls, and talkSeconds, plus totals. Counts human-handled calls; AI-handled calls and imported calls with no member are excluded. |
All three require startDate (inclusive) and endDate (exclusive), as ISO
datetimes with an offset. Resolve calendar dates in
getMyProfile.resolvedTimezone before calling. Windows are limited to 93
calendar days; split a longer range. These are live reads, separate from the
nightly analytics below, and do not charge the analytics rate-limit bucket.
Without userIds, a key owner holding VIEW_ALL_PHONES gets the
organization-wide result; otherwise only their own activity is returned.
With that capability, userIds narrows the read to named members and
countOutboundTexts.otherSenders is null. Naming a teammate without the
capability is refused. Named members appear even when their counts are zero.
Member text counts exclude AI-employee and workflow sends even when those
use the member’s line.
For calls, connectedCalls means status COMPLETED; conversationCalls
requires a connected call lasting at least 120 seconds or having a transcript
or AI summary. talkSeconds sums connected-call durations, using zero when
duration is missing. These human-only counts can be lower than the nightly
analytics, which can credit AI-handled calls to a member.
Team members (ADMIN scope)
| operationId | What it does |
|---|---|
changeTeamMemberRole |
Change a userId from listTeamMembers to role: ADMIN (every permission; moving to it drops the member’s permission settings) or MEMBER (what they may do is the permissions an admin sets in the app), effective immediately. A change leaving no active admin is refused. |
removeTeamMember |
Suspend a teammate, removing access and freeing their seat; optionally record a reason. Their open tasks go to the key owner, contact point-person seats are released, and workflow-step and lead-routing assignments are removed. Self-removal is refused. |
restoreTeamMember |
Restore a suspended teammate’s access and seat, subject to the organization’s seat policy. An already-active member is unchanged. Handed-over work stays where it went. |
Member permissions (ADMIN scope)
| operationId | What it does |
|---|---|
getTeamMemberCapabilities |
A teammate’s permissions as Manage permissions shows them: the capabilities they hold, by userId from listTeamMembers. Admins hold all of them. Your own are getMyCapabilities on the Account API. |
grantTeamMemberCapability |
Turn one permission (capability) on for a teammate. Their role does not change; an admin already holds everything. |
revokeTeamMemberCapability |
Turn one permission off for a teammate; grantTeamMemberCapability turns it back on. An admin cannot lose one this way — change the role instead. |
Teams (user groups)
| operationId | Scope | What it does |
|---|---|---|
listTeams |
READ |
The organization’s teams and their members. Optional search. |
createTeam |
ADMIN |
Create a team: name, optional description, emoji, color, memberUserIds. |
updateTeam |
ADMIN |
Edit a team. memberUserIds, when sent, replaces the member list. |
setTeamMembers |
ADMIN |
Replace a team’s members. |
deleteTeam |
ADMIN |
Delete a team for good. Refused while workflows, forms, or filters still use it: pass the dependencyResolution that getDeletionImpact returns (target kind USER_GROUP). Irreversible. |
Goal plans
A goal plan holds one person’s targets for a month: commission goals (in cents,
for one pipeline or all, counting EARNED or TOTAL) and personal goals.
Each month has at most one active plan and one draft; you edit the draft and
publish it.
| operationId | Scope | What it does |
|---|---|---|
getGoalPlan |
READ |
The key owner’s draft and active plan for the month starting periodStartDate. |
createGoalPlan |
WRITE |
Open the key owner’s draft for a month, seeded with the active plan’s commission goals. An existing draft is returned instead. |
upsertCommissionGoal |
WRITE |
Add (omit id) or change a commission target on a draft: metric (EARNED or TOTAL), targetCents greater than 0, optional pipelineId (omit for all pipelines). |
upsertPersonalGoal |
WRITE |
Add or edit a personal goal on a draft: title, optional description and displayOrder. |
updatePersonalGoalStatus |
WRITE |
Mark a personal goal ACTIVE, COMPLETED, or ARCHIVED. |
deletePersonalGoal |
WRITE |
Delete a personal goal from a draft. Irreversible; ARCHIVED keeps it instead. |
publishGoalPlan |
WRITE |
Make a draft the month’s active plan; the previous active plan is archived. |
Each has an ADMIN twin that acts on a named teammate (userId):
getTeammateGoalPlan, createTeammateGoalPlan,
upsertTeammateCommissionGoal, upsertTeammatePersonalGoal,
updateTeammatePersonalGoalStatus, deleteTeammatePersonalGoal, and
publishTeammateGoalPlan. The key owner must be an organization admin who
can see the team directory.
Team invites (ADMIN scope)
| operationId | What it does |
|---|---|
listTeamInvites |
List the organization’s team invitations (pending + spent/revoked, single-use + permanent). Each id maps to the accept URL /accept-invite/{id}. |
createTeamInvite |
Create an invite. userType sets the role: ADMIN or MEMBER (default MEMBER). Pass emails to email each address its own single-use invite, or isPermanent: true for the reusable link, which emails nobody and invites as MEMBER (a live older link is returned with its own role). |
revokeTeamInvite |
Revoke an invitation by id — the link stops working immediately. |
resendTeamInvite |
Re-send a live invitation’s email using invitationId. Keeps the same invitation and accept URL. Spent, revoked, or permanent invitations are refused; use emailPermanentTeamInvite for a reusable link. |
emailPermanentTeamInvite |
Email the organization’s existing permanent invite link to 1–50 emails. Normalized duplicates are sent once. Create the reusable link first with createTeamInvite(isPermanent: true); this operation does not create one. |
Team analytics (ADMIN scope)
Reporting reads over the same nightly snapshots as the web app’s Analytics
pages — each response carries the asOfDate it was computed. Both take an
optional period: SEVEN_DAYS | FOURTEEN_DAYS | THIRTY_DAYS |
YEAR_TO_DATE (default THIRTY_DAYS). The schema also lists SIXTY_DAYS
and THIS_MONTH, but these analytics operations reject them with BAD_USER_INPUT.
| operationId | What it does |
|---|---|
getTeamAnalyticsOverview |
Team performance overview — org-wide activity totals with prior-period deltas, per-agent rows (calls, texts, appointments, lead buckets, score), and per-agent pipeline outcomes. |
getTeamActivityTimeseries |
Daily team activity rows — calls, texts, emails, tasks, appointments, active agents, new leads per day. For charting trends. |
Example
Pull the last 7 days of team activity for a dashboard:
curl -X POST https://server.goliathdata.com/api/v1/call \
-H "Authorization: Bearer gsk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "operationId": "getTeamActivityTimeseries", "variables": { "period": "SEVEN_DAYS" } }'
Full variable schemas, response shapes, and worked examples for every operation are available from the discovery endpoint.