Get a team
One team and its full membership, pending invitations included.
On this page
One team in the shape List teams returns, plus its
membership. Reading a team is how you turn a user_id from elsewhere in the API,
on a generation for instance, into a person you can name.
Requires the MANAGE_TEAMS permission on the company the team belongs to. The
path team_id also names that company, so there is no separate selector.
That permission comes from the caller's company role, which is a separate
grant from their team role. Get identity returns it under
company_permissions, not in the permissions map beside it. See
Two roles, two maps.
https://api2.rundiffusion.com/api/v2/teams/{team_id}Request
Headers
AuthorizationstringRequired- Bearer token. This endpoint accepts an OAuth device flow token or a Company API Access Token. A Personal API Access Token is refused. See Authentication.
Authorization: Bearer eyJhbGciOi…
Path parameters
team_idstringRequired- The team to read, from List teams. It also names the company, so no separate selector is needed. A team in another company returns 404.
https://api2.rundiffusion.com/api/v2/teams/2D8NEx…
curl "https://api2.rundiffusion.com/api/v2/teams/2D8NEx…" \
-H "Authorization: Bearer $RUNDIFFUSION_TOKEN"const team = await fetch(
'https://api2.rundiffusion.com/api/v2/teams/2D8NEx…',
{ headers: { Authorization: `Bearer ${process.env.RUNDIFFUSION_TOKEN}` } },
).then(r => r.json());team = requests.get(
f"{BASE}/teams/{team_id}",
headers=HEADERS,
).json()Response
200 OK with the team and its members.
{
"id": "2D8NEx…",
"created": "2026-03-14T09:02:11+00:00",
"name": "Design Studio",
"is_active": true,
"members": [
{
"user_id": "k3PqV9…",
"email": "sam@example.com",
"created": "2026-03-14T09:03:40+00:00",
"is_pending": false,
"invitation_url": null,
"joined": "2026-03-14T09:04:52+00:00"
},
{
"user_id": null,
"email": "new_hire@example.com",
"created": "2026-05-02T11:20:07+00:00",
"is_pending": true,
"invitation_url": "https://app.rundiffusion.com/team-signup?teamName=Design%20Studio&teamId=2D8NEx…&inviteCode=8f14e45f…",
"joined": null
}
]
}The team's own fields are documented on List teams, so a client that parses the listing parses this for free.
Team member
user_idstring | null- The member's user ID. Always null while is_pending is true, since there is no user until someone accepts.
emailstring- The email address the membership belongs to.
createdstring (ISO 8601)- When the invitation was created, in UTC. Present whether or not it has been accepted, so it is the timestamp a pending member has, and what you sort or chase stale invitations by.
is_pendingboolean- Whether the invitation is still outstanding (not accepted yet).
invitation_urlstring | null- The link to send an invitee, or null once they have joined. It is the same link the dashboard copy button produces, so a link taken from either place is the same link. It carries a secret that grants membership of the team, so treat it as one.
joinedstring (ISO 8601) | null- When the member accepted, in UTC, or null while the invitation is still pending.
Members are ordered by email, and the list includes people who have been invited
but have not accepted. Branch on is_pending, which says exactly that.
created is there either way, so a pending member is not a row with no
timestamp: it is how you find invitations that have been sitting unanswered, and
paired with joined it tells you how long one took to accept.
Errors
Status codes
401UNAUTHENTICATED- Missing, malformed, or expired token. Refresh it and retry.
403PERMISSION_DENIED- The caller lacks MANAGE_TEAMS on the company, or presented a Personal API Access Token.
404TEAM_NOT_FOUND- No such team, or it belongs to another company. The two cases are deliberately indistinguishable.
429RATE_LIMITED- Too many requests. See Rate limits.
A team in another company returns 404, not 403. Holding MANAGE_TEAMS on
your own company says nothing about whether some other company's team exists, and
a 403 would answer that, so both cases return the same code and message.
