Overview
The Teams API enables programmatic management of teams, members, invitations, usage tracking, and access control. Base URL:/api/teams
Authentication: All endpoints require session authentication unless otherwise noted.
Team Identifiers: Endpoints accept either UUID (550e8400-e29b-xxxx-xxxxx-xxxxx) or numeric ID (123).
Default Team Selection
If you belong to multiple teams, you can set a default team. The default team affects which team context is used by the NanoGPT web app and other session-authenticated requests that support team billing and settings.Set Default Team
User Response Retention Default
Set a user-level default retention for/v1/responses. This applies when a request does not provide retention_days and no team override is active.
Get User Responses Retention
Set User Responses Retention
responsesRetentionDaysaccepts integer values0..365ornull.nullclears the user-level override.- The setting is stored in
sessions.metadata.responsesRetentionDays.
Referral Link
Referral links let you share a signup link that is tied to your account.Get or Create Referral Link
Error Response Format
All errors return JSON in this format:| Code | Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Session required |
FORBIDDEN | 403 | Insufficient permissions |
NOT_FOUND | 404 | Resource not found |
CONFLICT | 409 | Resource conflict (duplicate, wrong state) |
INVALID_INPUT | 422 | Validation failed |
RATE_LIMITED | 429 | Too many requests |
INTERNAL_ERROR | 500 | Server error |
Teams
List Teams
Returns all teams the authenticated user belongs to.Create Team
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | 2-50 characters. Letters, numbers, spaces, hyphens, underscores. |
409 CONFLICT: You already have a team with this name
Get Team Details
balancesshows the team owner’s account balancehigh_spend_text_discountindicates whether a high-spend discount is currently active for this team (when active, it applies automatically)responses_retention_daysis the optional team default for/v1/responsesretention (0..365ornull).roleis the requesting user’s role in this team
Update Team
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | 2-50 characters |
status | string | No | active, paused, or suspended |
Delete Team
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Must exactly match team name (confirmation) |
Members
List Members
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
limit | number | all | Results per page (max 100) |
Update Member Role
| Field | Type | Required | Description |
|---|---|---|---|
sessionId | number | Yes | Target member’s session ID |
role | string | Yes | admin or member (cannot set owner) |
403 FORBIDDEN: Cannot change the owner’s role400 INVALID_INPUT: Cannot change your own role
Update Member Usage Limits
| Field | Type | Required | Description |
|---|---|---|---|
sessionId | number | Yes | Target member’s session ID |
usage_limit_usd | number|null | No | Monthly limit in USD, or null to use team default |
usage_limit_enforced | boolean | No | Hard-enforce the limit (blocks usage when exceeded) |
Remove Member
403 FORBIDDEN: Cannot remove the team owner400 INVALID_INPUT: Cannot remove yourself (use/leave)
Get Own Preferences
Returns the authenticated user’s preferences for this team.effective_*fields show the resolved limit (member override or team default)
Update Own Preferences
| Field | Type | Required | Description |
|---|---|---|---|
bill_to_team | boolean | No | Bill usage to team or personal account |
name | string | No | Display name (1-100 characters) |
Leave Team
403 FORBIDDEN: Owner must transfer ownership before leaving
Invitations
List Pending Invitations
Send Invitation
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Valid email address |
role | string | No | admin or member (default: member) |
Revoke Invitation
| Field | Type | Required | Description |
|---|---|---|---|
action | string | No | Must be revoke (default) |
id | string | No* | Invitation UUID |
token | string | No* | Invitation token (min 16 chars) |
id or token
Response:
Accept Invitation
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Invitation token (min 16 characters) |
409 CONFLICT: Invitation is not pending409 CONFLICT: Invitation has expired
Lookup Invitation
Public endpoint to check invitation details before accepting.Invite Links
Get Invite Link Status
Enable/Disable Invite Link
| Field | Type | Required | Description |
|---|---|---|---|
action | string | No | enable (default) or disable |
Send Invite Link via Email
| Field | Type | Required | Description |
|---|---|---|---|
emails | string[] | Yes | 1-10 valid email addresses |
403 FORBIDDEN: Invite link is disabled429 RATE_LIMITED: Too many emails
Join via Invite Link
Cancel Join Request
Join Requests
List Join Requests
Accept/Reject Join Request
| Field | Type | Required | Description |
|---|---|---|---|
action | string | No | accept (default) or reject |
id | string | Yes | Join request UUID |
Delete Join Request
Delete a processed (non-pending) join request.409 CONFLICT: Cannot delete a pending request (must accept/reject first)
Usage & Billing
Get Team Usage
| Parameter | Type | Default | Description |
|---|---|---|---|
from | string | - | Start date (ISO format) |
to | string | - | End date (ISO format) |
Notes:
- Team-billed usage is charged against the team’s balances (shown on
GET /api/teams/{teamUuid}). - Individual members can choose whether to bill to the team or their personal account via
PATCH /api/teams/{teamUuid}/members/self(bill_to_team).
High-Spend Text Discount
Some teams may automatically qualify for discounted pricing on text model usage. When active,GET /api/teams/{teamUuid} will show:
Settings
Update Team Settings
| Field | Type | Required | Description |
|---|---|---|---|
default_member_usage_limit_usd | number|null | No | Default monthly limit for members |
team_usage_limit_usd | number|null | No | Team-wide spending limit |
responses_retention_days | number|null | No | Team default retention for /v1/responses (0..365). Use null to clear |
usage_limit_enforced | boolean | No | Hard-enforce limits |
BYOK (Team Settings & Provider Keys)
Teams can store provider keys and configure how team-billed traffic uses BYOK. For provider slugs and key formats (including JSON-based credentials like AWS/Azure), seeapi-reference/miscellaneous/byok.
Rate Limits:
- Key management (list/add/revoke): 5 operations per minute per team
- Key validation: 10 requests per minute per team
Get BYOK Settings
| Mode | Behavior |
|---|---|
disabled | Team BYOK is off |
prefer_team | Use team keys when available; otherwise fall back |
require_team | Require team keys; fail if missing |
Update BYOK Settings
List Team Provider Keys
Add or Replace a Team Provider Key
Revoke a Team Provider Key
Validate a Team Provider Key (Optional Preflight)
- In
prefer_teammode, team-billed traffic will not use a member’s personal BYOK keys unless the client explicitly enables BYOK for the request.
Model Access Control
Get Allowed Models
Update Allowed Models
| Field | Type | Required | Description |
|---|---|---|---|
allowed_models | object|null | Yes | Map of model keys to boolean, or null for all |
allowed_models: nullmeans all models are allowed.- When
allowed_modelsis an object, only models with a value oftrueare allowed for non-owners. Any missing models (or models withfalse) are blocked. - An empty object
{}blocks all models for non-owners. - Team owners are not restricted by the allowlist.
Ownership
Transfer Ownership
| Field | Type | Required | Description |
|---|---|---|---|
sessionId | number | Yes | New owner’s session ID |
- Current owner becomes admin
- Target member becomes owner
409 CONFLICT: Target is already the owner400 INVALID_INPUT: Cannot transfer ownership to yourself
Role Reference
| Feature | Owner | Admin | Member |
|---|---|---|---|
| View team details | Yes | Yes | Yes |
| Update team (name/status) | Yes | Yes | No |
| Delete team | Yes | No | No |
| List members | Yes | Yes | Yes |
| Change member roles | Yes | Yes | No |
| Set member usage limits | Yes | Yes | No |
| Remove members | Yes | Yes | No |
Update own preferences (/members/self) | Yes | Yes | Yes |
| Manage invitations | Yes | Yes | No |
| Manage invite link | Yes | Yes | No |
| Send invite link email | Yes | Yes | No |
| View join requests | Yes | Yes | No |
| Accept/reject join requests | Yes | Yes | No |
| Delete processed join requests | Yes | Yes | No |
View team usage (/usage) | Yes | Yes | Yes |
Update team settings (/settings) | Yes | Yes | No |
| View allowed models | Yes | Yes | Yes |
| Update allowed models | Yes | Yes | No |
| Transfer ownership | Yes | No | No |
| View BYOK settings | Yes | Yes | Yes |
| Update BYOK settings | Yes | Yes | No |
| List team provider keys | Yes | Yes | Yes |
| Add/revoke team provider keys | Yes | Yes | No |
| Validate team provider keys | Yes | Yes | No |
Rate Limits
| Endpoint | Limit |
|---|---|
POST /api/teams/{teamUuid}/invite-link/email | 5 emails per minute |
Webhooks (Coming Soon)
Future webhook events:team.member.joinedteam.member.removedteam.usage.limit_reachedteam.status.changed