Jump to a section
API reference · v1
ClipSent API
A REST API over HTTPS with JSON bodies. Base URL https://api.clipsent.com/v1. New here? Start with the overview.
The API opens with early access. This is the contract we’re building to; it may still change before then.
Authentication
Send your secret key as a bearer token. Keys belong to a workspace; create and revoke them in Settings → API keys.
Authorization: Bearer cs_live_4f…
| Prefix | Behavior |
|---|---|
cs_test_ | Makes watermarked clips that never count toward your plan. Webhooks still fire. |
cs_live_ | Makes real clips, published and billed. |
Keys are secret: use them from your server, never a browser or app.
Connect apps (OAuth)
Apps that act for ClipSent users (CRMs, website builders, form tools) use OAuth 2.0 with PKCE instead of API keys, so users never copy a key.
- Register your app with us to get a
client_idand your redirect URLs. - Send the user to
https://clipsent.com/oauth/authorize?client_id=…&redirect_uri=…&scope=clips:write events:read&state=…&code_challenge=…&code_challenge_method=S256. They sign in and approve. - Exchange the returned
codeat POSThttps://api.clipsent.com/oauth/tokenfor an access token (one hour) and a refresh token. - Call the API with
Authorization: Bearer <access token>, exactly as with a key.
| Scope | Allows |
|---|---|
clips:write | Create, approve, regenerate and unpublish clips. |
clips:read | Read clips, their links and stats. |
events:read | Read view events and manage webhook endpoints. |
templates:read | List templates and personas. |
The user sees exactly what your app asks for and can disconnect it any time from Settings → Connected apps. Apps can never create or change a Persona.
Conventions
Every object has an id with a prefix that says what it is, an object type, and created_at in UTC, ISO 8601.
req_ request | clp_ clip | bat_ batch | rcp_ recipient |
tpl_ clip template | ptpl_ page template | doc_ document | per_ Persona |
kc_ collection | ke_ entry | ans_ answer | rt_ route |
src_ source | wh_ webhook endpoint | evt_ event | file_ file |
Most objects take metadata: up to 20 string pairs of your own, returned everywhere the object appears. Add expand[]=recipient (or template, persona, request) to include a related object instead of its id. Test keys see only test objects.
Errors
Errors use HTTP status codes and a JSON body with a stable code you can branch on.
{
"error": {
"type": "invalid_request",
"code": "template_not_found",
"message": "No template tpl_reply_to_reqest in this workspace.",
"param": "template"
}
}
| Status | Type | When |
|---|---|---|
| 400 | invalid_request | A missing or malformed parameter. |
| 401 | authentication | No key, or a revoked one. |
| 402 | plan_limit | Your plan’s clips are used up and your cap is reached. |
| 403 | permission | The key may not use this persona or template. |
| 404 | not_found | No such object in this workspace. |
| 409 | conflict | The clip is in the wrong state, such as approving a published clip. |
| 422 | unprocessable | The material can’t be used: a page that won’t load, a file we can’t read. |
| 429 | rate_limit | Too many requests; retry after Retry-After seconds. |
| 5xx | api_error | Our fault. Safe to retry with the same idempotency key. |
Idempotency
Send Idempotency-Key on any POST. A retry with the same key within 24 hours returns the first response instead of doing the work twice. Use something unique to the event, such as your job or deal id.
Pagination
List endpoints return newest first, up to limit (default 20, at most 100) items, and a next cursor. Pass it as cursor to get the next page; next is null on the last page.
{ "data": [ … ], "next": "eyJpZCI6ImNscF83SGsy…" }
Rate limits
Up to 10 requests a second per workspace, and up to 100 clips rendering at once; more wait in a queue. Every response carries RateLimit-Remaining and RateLimit-Reset.
The request object
A request is whatever starts a clip: a form submission, a forwarded email, a job post, a CRM change, an API call. ClipSent keeps it, routes it to a template, and links every clip made from it.
{
"id": "req_4Fz8",
"object": "request",
"channel": "email",
"from": { "name": "Maria Lopez", "email": "maria@example.com" },
"summary": "3 bedrooms near schools, under $600k, moving by March",
"fields": { "budget": 600000, "beds": 3, "move_by": "2027-03-01", "area": "north side" },
"material": [{ "type": "text", "value": "Hi, we’re looking for 3 bedrooms…" }],
"route": "rt_buyers",
"clips": ["clp_7Hk2Qe"],
"status": "clip_drafted",
"received_at": "2026-10-25T09:02:11Z"
}
fields are read from the request by your route’s template (budget, beds, area…) and are what queries like request.budget use. status: received, routed, clip_drafted, ignored, held (a sender you haven’t allowed).
Requests
POST /v1/requests | Send a request from your own system: channel, from, material, optional fields and route. Routing decides whether a clip is drafted. |
GET /v1/requests | List requests. Filter by status, channel, route, received_after. |
GET /v1/requests/{id} | A request, its fields and the clips made from it. |
POST /v1/requests/{id}/clips | Make a clip from this request with a template of your choice, outside its route. |
POST /v1/requests/{id}/ignore | Mark it handled without a clip. |
POST /v1/requests/{id}/release | Accept a held request from a sender you haven’t allowed yet, and allow them from now on with { "allow_sender": true }. |
Routes
A route decides what happens to a request: which template it gets, which Persona, and whether to draft a clip at once. Each request address and connected app points at a route.
GET /v1/routes | List routes. |
POST /v1/routes | Create one: name, match (channel, sender, words), template, page_template, persona, approval. |
PATCH /v1/routes/{id} | Change it. |
DELETE /v1/routes/{id} | Remove it; its requests are kept. |
POST /v1/routes/{id}/test | Run a sample request through it and see the fields read and the template chosen, without making a clip. |
Request inbox
Every workspace has private request addresses, such as dana@in.clipsent.com. An email sent or forwarded there (a website form notification, a Zillow or Realtor.com lead, a lead ad) becomes a clip: ClipSent reads the person’s name, contact and request from the email and makes a clip with that address’s template, waiting for approval.
Create addresses, each with its own template, approval and call to action, in Settings → Request inbox. Clips made this way carry "source": { "type": "email", "from": "…", "subject": "…" } and fire the same webhooks. Only senders you allow are accepted; anything else is held for you to review.
The clip object
One clip, for one person.
{
"id": "clp_7Hk2Qe",
"object": "clip",
"status": "ready",
"template": "tpl_quote_walkthrough",
"persona": "per_dana",
"recipient": { "name": "Northwind", "email": "ops@northwind.example", "company": "Northwind" },
"request": "req_4Fz8",
"scenes": [
{ "key": "hello", "speaker": { "type": "take", "take": "take_intro" }, "visual": null },
{ "key": "store", "speaker": { "type": "ai_bubble", "text": "Your store takes six seconds to load…" },
"visual": { "type": "screen", "url": "https://northwind.example" } },
{ "key": "savings", "speaker": { "type": "ai_voice", "text": "Here’s what that costs you…" },
"visual": { "type": "chart", "data": "facts.monthly_loss" } },
{ "key": "plan", "speaker": { "type": "ai_voice", "text": "…" }, "visual": { "type": "points", "items": ["…"] } },
{ "key": "close", "speaker": { "type": "take", "take": "take_closing" }, "visual": null }
],
"facts": [
{ "key": "price", "value": "$21,400", "source": "material:quote", "as_of": "2026-10-25" },
{ "key": "utility_rate", "value": "$0.31/kWh", "source": "src_utility_rates", "as_of": "2026-10-01" },
{ "key": "inverter_warranty", "value": "12 years", "source": "answer:q_1", "as_of": "2026-10-25" }
],
"questions": [],
"video": { "duration": 72.4, "poster": "https://…/poster.jpg", "preview": "https://…/preview.gif" },
"links": {
"watch": "https://clipsent.com/c/7Hk2Qe",
"page": "https://clipsent.com/p/7Hk2Qe",
"embed": "<iframe src=\"https://clipsent.com/e/7Hk2Qe\" …></iframe>",
"email_html": "https://api.clipsent.com/v1/clips/clp_7Hk2Qe/email"
},
"seal": { "verify": "https://clipsent.com/verify/9Qm…" },
"stats": { "opens": 3, "plays": 2, "max_percent": 85, "clicks": 1, "last_seen_at": "2026-10-25T18:42:11Z" },
"metadata": { "deal_id": "D-1042" },
"created_at": "2026-10-25T17:01:03Z",
"ready_at": "2026-10-25T17:04:40Z"
}
Status
editing | Writing the scenes from the material, your Knowledge and your sources. |
needs_input | Something the template needs isn’t in the material, your Knowledge or your sources; questions says what. Nothing is guessed. Answer to continue. |
needs_approval | Waiting for you to approve the script (approval manual). |
rendering | Making the video, pages and email. |
ready | Published. Links work. |
failed | It couldn’t be made; error says why. Not billed. |
unpublished | Taken down. Links show that the clip is no longer available. |
POST /v1/clips
Make a clip for one person. Returns 202 with the clip in status editing.
Every clip answers someone: send a request, or a relationship saying how you know them. There is no way to make a clip for a stranger.
| Parameter | Description |
|---|---|
template required | The template id, such as tpl_reply_to_request. |
recipient required | Who it’s for: name (required), email, company, locale (language of the clip, default your Persona’s). |
request or relationship one required | The request this answers, or { "type": "client" | "subscriber" | "introduced" | "applicant", "crm_id": …, "consent_at": …, "introduced_by": … }. Subscribers need an opt-in date; unsubscribed people are refused. |
material required | What the clip is about: a list of { "type": "url" | "text" | "file", "value": … }. URLs must be public; files are ids from file uploads. Up to 10 items. |
sources | Ids of connected data sources to draw facts from. Defaults to the template’s. |
persona | Whose clip it is. Defaults to the key owner’s Persona. Using someone else’s needs their permission in the workspace. |
page_template | Also make a content page from this page template. |
approval | manual (default) holds the script for you; auto publishes when the template’s rules pass. |
call_to_action | { "label": …, "url": … }, overriding the template’s. |
metadata | Up to 20 string key–value pairs, returned on the clip and its webhooks. |
curl https://api.clipsent.com/v1/clips \
-H "Authorization: Bearer $CLIPSENT_KEY" \
-H "Idempotency-Key: job-8812" \
-d '{
"template": "tpl_quote_walkthrough",
"recipient": { "name": "Northwind" },
"material": [{ "type": "url", "value": "https://northwind.example/brief" }],
"approval": "auto",
"metadata": { "job_id": "8812" }
}'
GET /v1/clips/{id}
Returns the clip, including its latest stats.
GET /v1/clips
Lists clips, newest first. Filters: status, template, persona, created_after, created_before, and metadata[key]=value. Paginated.
PATCH /v1/clips/{id}
Change a clip’s metadata, call_to_action or recipient details. Before it’s published you can also change page_template. A published clip’s script never changes; make a new clip instead.
Clip sections
GET /v1/clips/{id}/sections | The script, section by section, with the facts each one used. |
PATCH /v1/clips/{id}/sections/{key} | Replace a section’s text before approval. Your text is used as written. |
POST /v1/clips/{id}/sections/{key}/swap | Choose a different picked item, such as another case study: { "item": "ke_91" }. |
GET /v1/clips/{id}/facts | Every fact the clip used, with its source, entry or page, and date. |
POST /v1/clips/{id}/answers
Answers a clip’s open questions, such as { "answers": [{ "question": "q_1", "value": "12 years" }], "remember": true }. With remember, answers are saved to your Knowledge for future clips. Unanswered questions can be skipped with { "skip": ["q_1"] }; that part of the clip is left out.
ClipSent explains the material it’s given; it never changes an offer, adds a promise or fills a gap with a guess.
POST /v1/clips/{id}/approve
Approves a clip in needs_approval, optionally with edited scenes: { "scenes": [{ "key": "store", "text": "…" }] }. Edited text is used as written. Returns the clip in rendering.
POST /v1/clips/{id}/regenerate
Writes the AI scenes again, all of them or { "scenes": ["store"] }, with an optional note (“shorter, and mention the March deadline”). Allowed until the clip is published; a published clip is replaced by making a new one.
GET /v1/clips/{id}/email
The ready-to-send email: { "subject": …, "html": …, "text": … }. The video plays in mail apps that support it and shows an animated preview linking to the watch page elsewhere. Send it from your own mailbox or tool; ClipSent doesn’t send email to your recipients.
Embeds and sends
GET /v1/clips/{id}/embed | Embed code for any page, with options for size and autoplay muted. |
POST /v1/clips/{id}/sends | Record that you sent it: { "channel": "gmail", "to": "maria@example.com", "sent_at": … }. Sends from connected Gmail or Outlook are recorded for you. |
GET /v1/clips/{id}/sends | Where and when this clip was sent. |
Recording sends lets stats tell “not opened yet” from “never sent”.
DELETE /v1/clips/{id}
Takes the clip down. Its links stop showing the video, its seal shows it was withdrawn, and its stats are kept. A clip that’s still being made is cancelled and not billed.
Batches
Make many clips at once, such as a monthly report for every client.
POST /v1/batches | { "template": …, "items": [{ "recipient": …, "material": …, "fields": … }] }, up to 1,000 items, or a file id of a CSV. |
GET /v1/batches/{id} | Progress: how many are writing, need input, need approval, ready, failed. |
GET /v1/batches/{id}/clips | The clips in the batch. |
POST /v1/batches/{id}/approve | Approve every clip in the batch that passed its checks; anything flagged stays for you. |
POST /v1/batches/{id}/cancel | Stop clips not yet made. Nothing unmade is billed. |
Recipients
The people your clips are for. A recipient is created with their first clip and gathers every clip and request about them.
GET /v1/recipients | List recipients. Search by q (name, email, company). |
GET /v1/recipients/{id} | A recipient, their clips and how each was watched. |
PATCH /v1/recipients/{id} | Update name, email, company, metadata, or crm_id to link them to your CRM. |
DELETE /v1/recipients/{id} | Erase a recipient: their details, requests and watch history. Their clips are withdrawn. For privacy requests. |
GET /v1/clips/{id}/stats
What happened to one clip.
{
"opens": 3, "plays": 2, "max_percent": 85, "completed": false, "clicks": 1,
"first_opened_at": "2026-10-25T18:20:02Z",
"last_seen_at": "2026-10-25T18:42:11Z",
"scenes": [ { "key": "store", "watched": 2 }, { "key": "plan", "watched": 1 } ]
}
GET /v1/clips/{id}/events
Every view event, newest first: { "type": "progress", "percent": 50, "at": …, "device": "mobile" }. Types: open, play, progress (25, 50, 75), complete, click. We record no names, accounts or IP addresses of viewers. Paginated.
GET /v1/events
Every event in the workspace, newest first, the same ones webhooks send: clip, request, batch, Knowledge and source events. Filter by type, clip, recipient and since. Kept for 90 days. Use it to catch up after downtime.
Analytics
GET /v1/analytics/clips | Counts and rates over time: sent, opened, watched to 50% and to the end, clicked. Group by day, week, template, persona or route. |
GET /v1/analytics/templates/{id} | How one template performs, section by section: where people stop and which sections are rewatched. |
GET /v1/analytics/items | Which picked items (case studies, listings) appear in the clips people watch to the end and click. |
{ "group_by": "template", "from": "2026-10-01", "to": "2026-10-31",
"data": [{ "template": "tpl_quote_walkthrough", "sent": 42, "opened": 35,
"watched_50": 29, "completed": 21, "clicked": 9 }] }
The template object
A picked section is a query: a source (your Knowledge or a connected source), what to look for, and how many to pick. Values like request.budget come from the request the clip is made for.
GET /v1/templates lists your video and page templates; GET /v1/templates/{id} returns one with its scenes, so you know what material it expects. Each scene has a speaker (a real take, an ai_bubble or ai_voice) and a visual (photo, chart, points, map, screen, document or none). Templates are built and edited in the app.
{
"id": "tpl_buyer_inquiry", "object": "template", "kind": "video",
"name": "Buyer inquiry", "max_seconds": 120,
"scenes": [
{ "key": "hello", "speaker": { "type": "take", "take": "intro" } },
{ "key": "search", "speaker": { "type": "ai_bubble", "max_words": 30 },
"visual": { "type": "points", "from": "request.fields" } },
{ "key": "areas", "speaker": { "type": "ai_voice", "max_words": 60 },
"visual": { "type": "map", "source": "knowledge", "collection": "neighborhoods",
"query": { "matches": "request.area" }, "pick": 2 } },
{ "key": "homes", "speaker": { "type": "ai_bubble", "max_words": 60 },
"visual": { "type": "photo", "source": "src_mcp_listings", "tool": "search_listings",
"query": { "status": "active", "max_price": "request.budget", "min_beds": "request.beds" },
"pick": [2, 3] } },
{ "key": "close", "speaker": { "type": "take", "take": "closing" } }
]
}
Clip template endpoints
GET /v1/templates | List clip templates. |
POST /v1/templates | Create one: name, sections, max_seconds, page_template, approval rules. |
GET /v1/templates/{id} | A template with its sections and their sources and queries. |
PATCH /v1/templates/{id} | Change it. Each change makes a new version; clips record the version they used. |
PUT /v1/templates/{id}/sections | Replace the sections in a new order. |
POST /v1/templates/{id}/test | Dry run with a sample request: the script, the facts each query found and any questions, without making or billing a clip. |
POST /v1/templates/{id}/duplicate | Copy it, for example to adapt one of your industry’s templates. |
GET /v1/templates/{id}/versions | Earlier versions and what changed. |
DELETE /v1/templates/{id} | Archive it. Existing clips keep working. |
Page templates
The page a clip plays on, built from blocks. Every page template also renders the clip’s email.
GET /v1/page-templates | List page templates. |
POST /v1/page-templates | Create one from blocks: clip, text, cards, map, estimate, calendar, cta, disclosures, and blocks for your industry, such as listing cards. |
GET /v1/page-templates/{id} | A page template with its blocks and their sources. |
PATCH /v1/page-templates/{id} | Change blocks, their order or their settings. Versioned like clip templates. |
POST /v1/page-templates/{id}/preview | Render it for a sample clip or request, as page or email HTML. |
DELETE /v1/page-templates/{id} | Archive it. |
Knowledge
Your workspace’s own source of facts: collections of structured entries (services, prices, listings, case studies), documents (PDFs, guides, past proposals) and answers saved from clips. Sections query it exactly like any connected MCP source, and every result a clip uses is cited with its entry or document, page and date.
All endpoints are listed under Knowledge endpoints.
Entries older than your review period (default six months) are flagged stale; a clip that would use one asks you first.
Knowledge endpoints
GET /v1/knowledge/collections | Collections and their fields. |
POST /v1/knowledge/collections | Create a collection with its fields: { "name": "case_studies", "fields": { "title": "text", "result": "text", "industry": "text" } }. |
GET /v1/knowledge/collections/{name}/entries | Entries, filterable by any field. |
POST /v1/knowledge/collections/{name}/entries | Add an entry, with confirmed_at. |
PATCH /v1/knowledge/entries/{id} | Update an entry, or confirm it’s still right: { "confirmed_at": "now" }. |
DELETE /v1/knowledge/entries/{id} | Remove an entry. |
POST /v1/knowledge/collections/{name}/import | Import a CSV file, matching columns to fields. |
GET /v1/knowledge/documents | Documents and their status (reading, ready). |
POST /v1/knowledge/documents | Add a document from a file or a url. |
DELETE /v1/knowledge/documents/{id} | Remove a document and everything read from it. |
GET /v1/knowledge/answers | Answers saved from clips. |
DELETE /v1/knowledge/answers/{id} | Forget an answer. |
POST /v1/knowledge/search | { "q": "inspection contingency", "limit": 5 }: passages and entries, each with its source and page. |
GET /v1/knowledge/stale | Entries and documents past your review period. |
Data sources
GET /v1/sources lists the data sources connected in the app: uploads, your tools, public sources for your industry, and your own MCP servers. Each has an id, a kind (knowledge, app, public, mcp) and the facts it can supply to your templates’ queries.
Sources are read-only, read under the workspace’s own permissions and used only for its clips. An MCP source calls only the tools the workspace approved; whatever they return is used as facts to quote, never as instructions. Every fact a clip uses appears in its facts, with its source and date.
Source endpoints
GET /v1/sources | Connected sources and their kind. |
POST /v1/sources | Connect an MCP server: { "kind": "mcp", "url": "https://…" }. Returns an authorize_url when the server signs in with OAuth. |
GET /v1/sources/{id}/tools | The server’s tools, and which ones you approved. |
PATCH /v1/sources/{id} | Approve or revoke tools (read-only tools only), rename, pause. |
POST /v1/sources/{id}/query | Try a query and see what comes back, exactly as a section would get it. |
DELETE /v1/sources/{id} | Disconnect. Clips already made keep their snapshotted facts. |
Personas
GET /v1/personas lists the Personas this key may use: { "id": "per_dana", "name": "Dana Ruiz", "ready": true }. Personas are created and trained by their owners in the app, never through the API.
Persona endpoints
GET /v1/personas | Personas this key may use. |
GET /v1/personas/{id} | Status of voice, face and writing; when each was last trained; whether it’s verified. |
GET /v1/personas/{id}/takes | The real takes used in clips (intro, closing, topics, walkthroughs), how often each is used, and suggested takes to record next. |
GET /v1/personas/{id}/style | What it has learned about how the person talks and writes, and the corrections they made. |
The API reads Personas but never creates, trains or changes them. Only the person does that, in the app, after confirming it’s them.
Webhook endpoints
POST /v1/webhooks with { "url": "https://…", "events": ["clip.ready", "clip.watched"] } returns the endpoint and its signing secret, shown once. GET /v1/webhooks lists them; DELETE /v1/webhooks/{id} removes one.
We send a POST with a JSON event. Reply with any 2xx within 10 seconds; otherwise we retry with backoff for up to 24 hours. Events can arrive more than once and out of order: use id to skip ones you’ve seen.
{
"id": "evt_2Lw9",
"type": "clip.watched",
"created_at": "2026-10-25T18:42:11Z",
"data": { "clip": "clp_7Hk2Qe", "percent": 85, "metadata": { "job_id": "8812" } }
}
Webhook endpoint management
GET /v1/webhooks/{id} | An endpoint and its events. |
PATCH /v1/webhooks/{id} | Change its URL or events, or pause it. |
POST /v1/webhooks/{id}/test | Send a sample event of a type you choose. |
GET /v1/webhooks/{id}/deliveries | Recent deliveries: status code, time taken, retries. |
POST /v1/webhooks/{id}/deliveries/{delivery}/retry | Send one again now. |
POST /v1/webhooks/{id}/rotate-secret | New signing secret; the old one keeps working for 24 hours. |
Event types
clip.needs_input | The clip has questions only you can answer. |
clip.needs_approval | A script is waiting for approval. |
clip.ready | Published; data holds the clip with its links. |
clip.failed | Couldn’t be made; data.error says why. |
clip.opened | Someone opened the watch or content page. |
clip.watched | Someone played it; sent at the first play and at 25, 50 and 75%, with percent. |
clip.completed | Someone watched to the end. |
clip.clicked | Someone used the call to action. |
clip.unpublished | The clip was taken down. |
clip.reported | The viewer tapped “I didn’t ask for this.” They won’t get clips from you again. |
More event types
request.received | A request arrived. |
request.held | A request from a sender you haven’t allowed is waiting. |
batch.completed | Every clip in a batch is made, flagged or failed. |
clip.sent | A send was recorded. |
knowledge.stale | Entries or documents passed your review period. |
source.error | A connected source failed or lost access. |
persona.updated | A Persona was retrained or re-recorded. |
Verifying signatures
Each delivery has a ClipSent-Signature header: t=<unix time>,v1=<hex>, where v1 is the HMAC-SHA256 of <t>.<raw body> with your endpoint’s secret. Compare in constant time and reject timestamps older than five minutes.
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return v1?.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
Standard video events
For data tools such as Segment and RudderStack, ClipSent sends watch events with the common video event names. Each carries session_id (the clip id), title, position and total_length in seconds, percent, source: "ClipSent" and your clip’s metadata.
| ClipSent | Sent as |
|---|---|
clip.opened | Video Player Loaded |
clip.watched (first play) | Video Playback Started |
clip.watched (25, 50, 75%) | Video Content Playing |
clip.completed | Video Content Completed |
clip.clicked | Clip CTA Clicked |
Events are anonymous by default. A workspace can choose to send the recipient’s email as userId for contacts it already has a relationship with; that’s the workspace’s own data, under its own consent.
Files
POST /v1/files | Upload a file (multipart, up to 200 MB): photos, PDFs, CSVs, video for material or Knowledge. Returns a file_ id. |
GET /v1/files/{id} | Its name, type, size and where it’s used. |
DELETE /v1/files/{id} | Remove it if nothing uses it. |
Workspace
GET /v1/workspace | Name, plan, time zone, review period for Knowledge, request addresses. |
GET /v1/usage | Clips this period, included and extra, data fees so far, and your cap. |
GET /v1/members | People in the workspace and their roles. |
GET /v1/audit | Who did what: approvals, template changes, connections, key use. Kept for a year. |
Verifying a clip (public)
Anyone can check a clip is real, with no key: GET https://api.clipsent.com/v1/seals/{seal}. It returns who the clip is from, that it was made with their Persona and approved by them, when, and whether it has since been withdrawn. Every clip page links to it.
{ "seal": "9Qm…", "from": "Dana Ruiz", "persona_verified": true,
"approved_by": "Dana Ruiz", "made_at": "2026-10-25T09:05:40Z",
"status": "valid", "made_with": "ClipSent" }
ClipSent MCP server
AI assistants that support MCP connect to https://clipsent.com/mcp and sign in with OAuth, acting only as the person who connected them. Tools:
create_clip | Draft a clip for a person from a template and their material. It waits for approval in the app, as always. |
list_clips | Recent clips and their status. |
get_clip_stats | Who opened and how far they watched. |
list_templates | The templates available. |
search_knowledge | Search your Knowledge; answers cite their source. |
remember | Save an answer to your Knowledge, such as “our inverter warranty is 12 years”. |