API and MCP reference

Brands

9 operations. Each REST operation is also an MCP tool of the same name. REST https://tlntconnect.com/api/v1

GET/api/v1/brandsThe workspace's brands (clients), by name; q searches name, website and industry.

Every brand of the workspace, as every agency member sees the brands page: id, name, website, industry, contact_name, contact_email, notes, logo_url, created_at, updated_at. Sorted by name; filter by industry; paged with page/limit (limit ≤ 100, default 50).

MCP tool
list_brands
Scopes
brands:read
Members
admin, manager, scout, viewer
Idempotency-Key
Ignored (read)
Rate weight
1

Input

limit queryinteger — Page size, default 50.
page queryinteger — 1-based page, default 1.
industry querystring — Exact industry.
q querystring — Search in name, website and industry.

Responses

200Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
429rate_limited (honour Retry-After)
500internal_error
POST/api/v1/brandsCreate a brand with optional contacts (the first is primary) and segments.

Creates a brand through the canonical service (createBrandFromInput — one atomic RPC with its contacts and segment memberships, the same as the app and Atlas). segment_ids must be segments of this workspace. Returns 201 with the brand.

MCP tool
create_brand
Scopes
brands:write
Members
admin, manager
Idempotency-Key
optional
Rate weight
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.
contacts bodyarray of object
industry bodystring | null
name body, requiredstring
notes bodystring | null
segment_ids bodyarray of string (uuid)
website bodystring | null

Responses

201Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
409idempotency_key_reused / idempotency_in_progress / idempotency_context_changed / idempotency_response_too_large
429rate_limited (honour Retry-After)
500internal_error / idempotent_replay_of_failure
503service_unavailable
GET/api/v1/brands/{brand_id}One brand with its contacts (primary first) and segments.

One brand: the list columns plus contacts (id, name, email, title, department, phone, linkedin_url, notes, is_primary, status, updated_at — primary first) and segments (id, name, slug). Contact fields come from outside the agency and are labelled untrusted. Unknown or cross-workspace ids return 404.

MCP tool
get_brand
Scopes
brands:read
Members
admin, manager, scout, viewer
Idempotency-Key
Ignored (read)
Rate weight
1
Untrusted fields
contacts

Input

brand_id path, requiredstring (uuid) — Brand id in this workspace.

Responses

200Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
429rate_limited (honour Retry-After)
500internal_error
PATCH/api/v1/brands/{brand_id}Update a brand's name, website, industry, notes, primary contact fields or segments. Send expected_updated_at.

Partial update through the canonical service (updateBrandFromInput, the same versioned RPC as the app). expected_updated_at (the updated_at from GET /brands/{id}) is required: missing is 428 expected_updated_at_required, a brand changed since is 409 stale_target and nothing is written. segment_ids replaces the brand's segments (segments of this workspace).

MCP tool
update_brand
Scopes
brands:write
Members
admin, manager
Idempotency-Key
optional
Rate weight
1

Input

brand_id path, requiredstring (uuid) — Brand 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.
contact_email bodystring | null
contact_name bodystring | null
expected_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.
industry bodystring | null
name bodystring
notes bodystring | null
segment_ids bodyarray of string (uuid)
website bodystring | null

Responses

200Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
409stale_target / idempotency_key_reused / idempotency_in_progress / idempotency_context_changed / idempotency_response_too_large
428expected_updated_at_required
429rate_limited (honour Retry-After)
500internal_error / idempotent_replay_of_failure
503service_unavailable
DELETE/api/v1/brands/{brand_id}Delete a brand that has no deals. Runs directly within the daily delete cap unless this credential asks for approval in TLNT for deletes (202 pending_approval).

Deletes one brand, exactly as the app does: admin members only; a brand that still has deals is never deleted (409 conflict — reassign or delete the deals first); otherwise its contacts and segment memberships go with it and its invoices, files, casting calls and linked emails are detached, atomically. A `delete`-class action (brands:read + delete): by default it deletes at once (200 { status: "deleted" }) within the credential's daily delete cap. 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 brand.delete action); poll GET /actions/{action_id}. With expected_updated_at, a brand changed since is 409 stale_target.

MCP tool
delete_brand
Scopes
brands:read + delete
Members
admin
Approval
Runs directly; queued when the credential asks for approval for delete
Idempotency-Key
required
Rate weight
1

Input

brand_id path, requiredstring (uuid) — Brand 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

200Success
202pending_approval — queued for approval in TLNT (only when the credential asks for approval for this action class; it runs directly by default)
400invalid_input / invalid_json / invalid_id / idempotency_key_required
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
409stale_target / conflict / idempotency_key_reused / idempotency_in_progress / idempotency_context_changed / idempotency_response_too_large
429rate_limited (honour Retry-After) / daily_delete_cap_reached
500internal_error / idempotent_replay_of_failure
503service_unavailable
POST/api/v1/brands/{brand_id}/contactsAdd a contact to a brand; is_primary moves the brand's primary contact to it.

Adds a contact as the app does: the brand must be in this workspace (404), the email must be an address, is_primary makes it the brand's one primary contact. Returns 201 with the contact.

MCP tool
add_brand_contact
Scopes
brands:write
Members
admin, manager
Idempotency-Key
optional
Rate weight
1
Untrusted fields
notes

Input

brand_id path, requiredstring (uuid) — Brand 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.
department bodystring | null
email bodystring | null
is_primary bodyboolean
linkedin_url bodystring | null
name body, requiredstring
notes bodystring | null
phone bodystring | null
title bodystring | null

Responses

201Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
409idempotency_key_reused / idempotency_in_progress / idempotency_context_changed / idempotency_response_too_large
429rate_limited (honour Retry-After)
500internal_error / idempotent_replay_of_failure
503service_unavailable
PATCH/api/v1/brands/{brand_id}/contacts/{contact_id}Update a brand contact's fields, status or primary flag. Send expected_updated_at.

Partial update as the app does (email validated, status active | archived, the primary contact moves only by making another contact primary — un-setting the current one is 400). expected_updated_at (the contact's updated_at from GET /brands/{id}) is required: missing is 428, a contact changed since is 409 stale_target and nothing is written.

MCP tool
update_brand_contact
Scopes
brands:write
Members
admin, manager
Idempotency-Key
optional
Rate weight
1
Untrusted fields
notes

Input

brand_id path, requiredstring (uuid) — Brand id in this workspace.
contact_id path, requiredstring (uuid) — Contact id on this brand.
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.
department bodystring | null
email bodystring | null
expected_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.
is_primary bodyboolean
linkedin_url bodystring | null
name bodystring
notes bodystring | null
phone bodystring | null
status body"active" | "archived"
title bodystring | null

Responses

200Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
409stale_target / idempotency_key_reused / idempotency_in_progress / idempotency_context_changed / idempotency_response_too_large
428expected_updated_at_required
429rate_limited (honour Retry-After)
500internal_error / idempotent_replay_of_failure
503service_unavailable
GET/api/v1/brands/segmentsThe workspace's brand segments, by name.

Every brand segment of the workspace, sorted by name: id, name, slug, description, parent_id, created_at.

MCP tool
list_brand_segments
Scopes
brands:read
Members
admin, manager, scout, viewer
Idempotency-Key
Ignored (read)
Rate weight
1

Responses

200Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
429rate_limited (honour Retry-After)
500internal_error
POST/api/v1/brands/segmentsCreate a brand segment (its slug is derived from the name).

Creates a brand segment as the app does (slug derived from the name; parent_id must be a segment of this workspace). Returns 201 with the segment.

MCP tool
create_brand_segment
Scopes
brands:write
Members
admin, manager
Idempotency-Key
optional
Rate weight
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.
description bodystring | null
name body, requiredstring
parent_id bodystring (uuid) | null

Responses

201Success
400invalid_input / invalid_json / invalid_id
401missing_token / invalid_token / revoked_token / expired_token
403missing_scope / actor_unavailable / plan_upgrade_required / role_forbidden
404not_found (unknown, cross-workspace or not visible to the key's member)
409idempotency_key_reused / idempotency_in_progress / idempotency_context_changed / idempotency_response_too_large
429rate_limited (honour Retry-After)
500internal_error / idempotent_replay_of_failure
503service_unavailable