Outreach
10 operations. Each REST operation is also an MCP tool of the same name. REST https://tlntconnect.com/api/v1
GET/api/v1/outreach/templates
Every active outreach template in this workspace, as the app's Templates tab lists them: id, name, subject, body_html, body_text, variables, category (cold_intro, follow_up, social_proof, custom), created_at, updated_at and times_used (outreach emails sent with it). Templates carry merge fields — {{creator_first_name}}, {{display_name}}, {{brand_name}}, {{sender_name}}, {{tiktok_username}}, {{ig_username}}, {{email}}, {{total_reach}}, {{total_reach_formatted}}, {{platform}}, {{niche}} — that a send fills per recipient. Requires outreach:read.
list_outreach_templatesoutreach:read- admin, manager, scout, viewer
- Ignored (read)
- 1
Responses
POST/api/v1/outreach/templates
Creates an active outreach template in this workspace, owned by the key's member. Send name, subject and body_html or body_text (or both): HTML goes through the app's email sanitizer (400 invalid_input when nothing is left); a plain-text body alone becomes escaped HTML paragraphs, and an HTML body alone gets its text version derived. category defaults to cold_intro. Answers 201 with the template. Requires outreach:write and an admin or manager member.
create_outreach_templateoutreach: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.name body, requiredstring — Template name.subject body, requiredstring — Subject line; may carry merge fields.body_html bodystring — HTML body. Cleaned by the app's email sanitizer (scripts, styles and unsafe attributes are removed).body_text bodystring — Plain-text body. Given alone, the HTML body is rendered from it (paragraphs, escaped).category body"cold_intro" | "follow_up" | "social_proof" | "custom" — cold_intro (default), follow_up, social_proof or custom.variables bodyarray of string — Merge fields the template uses (informational).Responses
GET/api/v1/outreach/templates/{template_id}
One active outreach template of this workspace. Another workspace's id, or a deleted template, is 404. updated_at is the version to pass as expected_updated_at when you update or delete it. Requires outreach:read.
get_outreach_templateoutreach:read- admin, manager, scout, viewer
- Ignored (read)
- 1
Input
template_id path, requiredstring (uuid) — Outreach template id in this workspace.Responses
PATCH/api/v1/outreach/templates/{template_id}
Updates an active template of this workspace. Send at least one of name, subject, body_html, body_text, category, variables (400 invalid_input otherwise). body_html is sanitized; body_text alone replaces the body (its HTML is rendered from it). Optional expected_updated_at: a template changed since you read it is 409 stale_target. Another workspace's id, or a deleted template, is 404. Sends already queued for approval with this template are refused at approval if the edit changes what they would send. Requires outreach:write and an admin or manager member.
update_outreach_templateoutreach:write- admin, manager
- optional
- 1
Input
template_id path, requiredstring (uuid) — Outreach template 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.expected_updated_at bodystring — 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).name bodystring — Template name.subject bodystring — Subject line; may carry merge fields.body_html bodystring — HTML body. Cleaned by the app's email sanitizer (scripts, styles and unsafe attributes are removed).body_text bodystring — Plain-text body. Given alone, the HTML body is rendered from it (paragraphs, escaped).category body"cold_intro" | "follow_up" | "social_proof" | "custom" — cold_intro (default), follow_up, social_proof or custom.variables bodyarray of string — Merge fields the template uses (informational).Responses
DELETE/api/v1/outreach/templates/{template_id}
Deletes (retires) one outreach template, exactly as the app's delete does: it stops being offered, while the outreach history and stats that name it keep it. A `delete`-class action: by default it deletes at once and answers 200 { status: "deleted" }, within the credential's daily delete cap (429 daily_delete_cap_reached past it). When the credential asks for approval in TLNT for deletes, the call answers 202 { status: "pending_approval", action_id, approval_url } instead and a workspace admin or manager approves or rejects it in TLNT; poll GET /actions/{action_id}. The approver signs off on the template as it was when you asked: one edited before approval is not deleted (the action reports failed). Optional expected_updated_at: a template changed since you read it is 409 stale_target. Another workspace's id, or a deleted template, is 404. Requires the outreach:read and delete scopes, an Idempotency-Key, and an admin or manager member.
delete_outreach_templateoutreach:read+delete- admin, manager
- Runs directly; queued when the credential asks for approval for delete
- required
- 1
Input
template_id path, requiredstring (uuid) — Outreach template 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
POST/api/v1/outreach/preview
Renders the subject, HTML body and text body ONE recipient would receive — the same rendering a send uses (the request's fields over the template's, merge fields from the roster creator or, for an address, their fallbacks). Name exactly one of creator_id (a roster creator of this workspace; another workspace's id is 404) or recipient_email. Nothing is sent or saved. Merged creator names and profile fields are text authored outside the agency: subject, body_html, body_text and to_name are wrapped as untrusted content. Requires outreach:write.
preview_outreach_emailoutreach:write- admin, manager, scout, viewer
- Ignored (read)
- 1
data.to_namedata.subjectdata.body_htmldata.body_text
Input
creator_id bodystring (uuid) — A roster creator in this workspace.recipient_email bodystring — A literal address.template_id bodystring (uuid) — A template to start from: its subject and body fill whatever you leave out.subject bodystring — Subject line; merge fields are filled per recipient.body_text bodystring — Plain-text body (escaped into HTML paragraphs); merge fields are filled per recipient.body_html bodystring — HTML body instead of body_text, cleaned by the app's email sanitizer.Responses
POST/api/v1/outreach/send
Sends one outreach email per recipient — the same send as the app's composer (validation, merge fields, the mailbox's sender permission, outreach history, inbox thread). Not metered: no credits are charged. A creator is marked contacted only from an earlier pipeline stage (one who replied or signed up keeps their stage). Recipients: creator_ids (roster creators of THIS workspace — another workspace's id is 404) and/or recipient_emails (any valid address; one that belongs to roster creators is sent to each of them), at most 100 in all and at most 100 messages once addresses are resolved (400 invalid_input). Everything one request renders (subjects, bodies, recipients) may total at most 1,000,000 bytes (400 invalid_input, never truncated). Content: template_id and/or subject + body_text (or body_html, sanitized); the request's fields win over the template's, and merge fields ({{creator_first_name}}, {{display_name}}, {{brand_name}}, {{sender_name}}, …) are filled per recipient. Mailbox: email_account_id, or the member's first mailbox they can send from — another workspace's or one they cannot see is 404, one they may only read is 403 mailbox_permission_required, one that cannot send right now is 409 conflict. follow_up { after_days: 2-14 } schedules an auto follow-up for roster recipients where the plan includes it (403 feature_not_available otherwise). An `external_send`-class action: by default it sends at once and answers 200 { status: "sent", data: { sent, failed, already_sent, recipients[] … } }, counting each message against the credential's daily recipient cap (default 50, up to 500; 429 daily_send_cap_reached past it, Retry-After to 00:00 UTC) — for API keys and connected apps alike. When the credential asks for approval in TLNT for sending email, the call answers 202 { status: "pending_approval", action_id, approval_url } instead, an admin reads every recipient and every message verbatim in TLNT and approves or rejects; approving sends exactly that — if anything changed since (a creator renamed or re-addressed, the template edited, the mailbox grant revoked) nothing is sent and the action fails. Poll GET /actions/{action_id}. A database error before the first message leaves is 503 service_unavailable (nothing sent, the cap refunded; retry with the same key). Retrying with the same Idempotency-Key never sends twice: within 24 hours it replays the stored answer, and later every message already sent under that key (whatever happened to it since: delivered, opened, replied, bounced) is reported already_sent instead of being sent again. A new key is a new send. Creator names in the result are untrusted text. Requires outreach:write and email:send, an Idempotency-Key, and an admin or manager member. Rate weight 5.
send_outreach_emailoutreach:write+email:send- admin, manager
- Runs directly; queued when the credential asks for approval for external_send
- required
- 5
data.recipients[].to_namedata.errors[]
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.creator_ids bodyarray of string (uuid) — Roster creator ids in this workspace (at most 100 recipients in all).recipient_emails bodyarray of string — Literal addresses (at most 100 recipients in all). An address that belongs to a roster creator is sent as that creator; any other valid address is sent as typed.email_account_id bodystring (uuid) — The mailbox to send from. Default: the member's first mailbox they can send from.template_id bodystring (uuid) — A template to start from: its subject and body fill whatever you leave out.subject bodystring — Subject line; merge fields are filled per recipient.body_text bodystring — Plain-text body (escaped into HTML paragraphs); merge fields are filled per recipient.body_html bodystring — HTML body instead of body_text, cleaned by the app's email sanitizer.follow_up bodyobject — Schedule an auto follow-up for roster recipients (plans with auto follow-ups only).Responses
GET/api/v1/outreach/history
The outreach history the key's member sees on the app's Sent tab: admins see the workspace's; a manager sees their own sends and their assigned creators'; other members only their own. Filters: creator_id, template_id (another workspace's id is 404), status, q (subject, address or creator name). Paged with page/limit (limit ≤ 100, default 50) and totals. reply_text (the creator's reply as received), creator.display_name and subject (which carries merged creator fields) are text authored outside the agency, wrapped as untrusted content. Requires outreach:read.
list_outreach_historyoutreach:read- admin, manager, scout, viewer
- Ignored (read)
- 1
data[].reply_textdata[].creator.display_namedata[].subject
Input
page queryinteger — 1-based page, default 1.limit queryinteger — Page size, default 50.creator_id querystring (uuid) — Only this roster creator's history.template_id querystring (uuid) — Only sends of this template.status query"sent" | "delivered" | "opened" | "replied" | "bounced" | "failed" — Only this status.q querystring — Search subject, address or creator name.Responses
GET/api/v1/outreach/history/{log_id}
One outreach history entry the key's member can see (the Sent tab's visibility, as list_outreach_history). An entry they cannot see, or another workspace's, is 404. message_text is the HTML that was sent; reply_text is the creator's reply — they, subject and creator.display_name carry text authored outside the agency (merged creator fields, the reply) and are wrapped as untrusted content. Requires outreach:read.
get_outreach_history_entryoutreach:read- admin, manager, scout, viewer
- Ignored (read)
- 1
data.reply_textdata.message_textdata.creator.display_namedata.subject
Input
log_id path, requiredstring (uuid) — Outreach history entry id.Responses
GET/api/v1/outreach/stats
The workspace's outreach email statistics, as the app's Analytics tab shows them to every member: total, delivered, opened, replied, bounced and their rates (percent), by_template (template_id, template_name, sent, opened, replied, bounced) and daily_sends (date, count). Requires outreach:read.
get_outreach_statsoutreach:read- admin, manager, scout, viewer
- Ignored (read)
- 1
