Roster
12 operations. Each REST operation is also an MCP tool of the same name. REST https://tlntconnect.com/api/v1
GET/api/v1/roster
The workspace roster, as every staff member sees it in the app. Rows carry id, display_name, primary_platform, tiktok_username, ig_username, youtube_channel_id, x_username, total_reach, status, niche, primary_niche, former_at, created_at. Sorted by name; paged with page/limit (limit ≤ 100, default 50).
list_rosterroster:read- admin, manager, scout, viewer
- Ignored (read)
- 1
Input
include_former queryboolean — true adds off-roster (former) creators.limit queryinteger — Page size, default 50.page queryinteger — 1-based page, default 1.q querystring — Name search.Responses
POST/api/v1/roster
Adds a creator through the canonical roster create path (src/lib/roster/mutations.ts): allowlisted, normalised fields; 409 duplicate_creator (with existing_id) on a matching email/TikTok/Instagram handle; the trial roster cap (402 trial_limit_reached, exactly the refusal the app gives); billable-seat sync. The creator is assigned to the key's member. Returns 201 with id, display_name, status, created_at.
add_roster_creatorroster:write- admin, manager
- optional
- 1
Input
Idempotency-Key headerstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.email bodystring | nullig_username bodystring | nulllocation bodystring | nullniche bodyarray of string | string | null — Niches as an array of strings or one comma-separated string.primary_niche bodystring | nullprimary_platform bodystring | nullstatus body"discovered" | "qualified" | "queued" | "contacted" | "replied" | "signed_up" | "onboarded" | "activated" | "monetizing"tiktok_username bodystring | nulltotal_reach bodynumber | nullx_username bodystring | nullyoutube_channel_id bodystring | nulldisplay_name body, requiredstringResponses
GET/api/v1/roster/{creator_id}
Roster creator detail: the list columns plus location, ownership_status, bio and updated_at (pass updated_at back as expected_updated_at to update the creator). The bio is the creator's own text and is labelled untrusted. Unknown or cross-workspace ids return 404.
get_roster_creatorroster:read- admin, manager, scout, viewer
- Ignored (read)
- 1
bio
Input
creator_id path, requiredstring (uuid) — Roster creator id in this workspace.Responses
PATCH/api/v1/roster/{creator_id}
Partial update through the canonical roster write (src/lib/roster/mutations.ts — the same activity log, notifications and seat sync as the app), with the same field allowlist as create (nothing required). Pass null to clear a clearable field; present-but-invalid values are a 400, never a silent null. expected_updated_at (the updated_at from GET /roster/{id}) is required: missing is 428 expected_updated_at_required, a creator changed since is 409 stale_target and nothing is written. ownership_status (exclusive | non_exclusive | null) and former: false (restores a former creator to the active roster) move billable seats, so they need roster:write AND an admin member (403 role_forbidden otherwise) and sync the subscription's seat count; restoring a former creator past a trial's roster allowance is 402 trial_limit_reached. former: true is refused (400 invalid_input): archiving is archive_roster_creator (DELETE /roster/{id}), which needs the delete scope and runs directly within the daily delete cap unless the credential asks for approval in TLNT for deletes. Cross-workspace ids return 404.
update_roster_creatorroster:write- admin, manager
- optional
- 1
Input
creator_id path, requiredstring (uuid) — Roster creator id in this workspace.Idempotency-Key headerstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.email bodystring | nullig_username bodystring | nulllocation bodystring | nullniche bodyarray of string | string | null — Niches as an array of strings or one comma-separated string.primary_niche bodystring | nullprimary_platform bodystring | nullstatus body"discovered" | "qualified" | "queued" | "contacted" | "replied" | "signed_up" | "onboarded" | "activated" | "monetizing"tiktok_username bodystring | nulltotal_reach bodynumber | nullx_username bodystring | nullyoutube_channel_id bodystring | nulldisplay_name bodystringexpected_updated_at bodystring — The record's updated_at as you last read it (ISO 8601). Required on updates: a missing one is 428 expected_updated_at_required, an older one 409 stale_target.former bodyfalse — false restores a former creator to the active roster. Admin members only. To archive, use archive_roster_creator.ownership_status body"exclusive" | "non_exclusive" | null — exclusive | non_exclusive, or null to un-roster. Admin members only.Responses
DELETE/api/v1/roster/{creator_id}
Archives one roster creator — the reversible "former" soft delete the app's roster remove uses (delete_creators(): nothing is destroyed, campaigns, deliverables and payments stay). A `delete`-class action on an admin member's key with roster:write and delete: by default it archives at once (200 { status: "archived" }) within the credential's daily delete cap, and syncs billable seats. When the credential asks for approval in TLNT for deletes, the call answers 202 { status: "pending_approval", action_id, approval_url } instead and an admin approves or rejects it in TLNT (the Atlas roster.creator_archive action); poll GET /actions/{action_id}. An already-former creator is 409 conflict; with expected_updated_at, a creator changed since is 409 stale_target. Restore with PATCH /roster/{id} { former: false }.
archive_roster_creatorroster:write+delete- admin
- Runs directly; queued when the credential asks for approval for delete
- required
- 1
Input
creator_id path, requiredstring (uuid) — Roster creator id in this workspace.expected_updated_at querystring — The record's updated_at as you last read it. Optional: when given, a record changed since then is refused (409 stale_target). In a query string, URL-encode it (+ as %2B).Idempotency-Key header, requiredstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.Responses
GET/api/v1/roster/{creator_id}/notes
Internal notes on a roster creator, as every staff member sees them on the creator profile: id, content, is_pinned, author_id, created_at, updated_at; pinned first, then newest. At most 100. Cross-workspace ids return 404.
list_roster_notesroster:read- admin, manager, scout, viewer
- Ignored (read)
- 1
Input
creator_id path, requiredstring (uuid) — Roster creator id in this workspace.Responses
POST/api/v1/roster/{creator_id}/notes
Adds an internal note through the canonical note service (the same RPC and assignee notification as the app). Managers add notes only on creators assigned to them (403 otherwise), as in the app. content: 1-10,000 characters. Returns 201 with the note.
add_roster_noteroster:write- admin, manager
- optional
- 1
Input
creator_id path, requiredstring (uuid) — Roster creator id in this workspace.Idempotency-Key headerstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.content body, requiredstringResponses
POST/api/v1/roster/join-link
Mints a new roster join link (/join/<agency>.<code>), as the app's "Invite talent" does: anyone with it can ask to join the roster as a creator (a provisional creator waiting in TLNT), and every join link shared before stops working. A `public_share`-class action under share:public: by default it runs at once and answers 200 { status: "shared", data: { share_url } }, for API keys and connected apps alike, counting one of the credential's public links per day (default 25, up to 200; 429 daily_public_link_cap_reached past it). When the credential asks for approval in TLNT for public links, the call answers 202 { status: "pending_approval", action_id, approval_url } instead and a person approves or rejects it in TLNT — the card names exactly what becomes public and to whom; once approved, GET /actions/{action_id} carries result.share_url. Requires an Idempotency-Key.
create_roster_join_linkroster:read+share:public- admin, manager
- Runs directly; queued when the credential asks for approval for public_share
- required
- 1
Input
Idempotency-Key header, requiredstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.