GET/api/v1/brain/sources
List knowledge sources
The index of the clone's knowledge (title, type, words, status). Full text comes from the detail endpoint.
Query parameters
starting_afterinteger
Cursor: returns sources with id greater than this.
source_typestring
Values: youtube · text · pdf · video · website · instagram · vimeo
statusstring
Values: pending · extracting · processing · ready · error
curl "https://www.clonify.com/api/v1/brain/sources" \
-H "Authorization: Bearer clk_live_…"
POST/api/v1/brain/sources
Train the clone with text
Creates a text source, chunks it, embeds it and links it to all your clones. Same flow as the panel. Consumes the plan's word quota (403 words_quota_exceeded when empty).
Write permission
Body (JSON)
titlestring 2..200required
contentstring 10..200000required
content_dateYYYY-MM-DD
Date of the original content (not the upload). Omit = today.
external_idstring
YOUR stable id for this content. If you already uploaded one with this id, it is REPLACED (idempotent upsert for syncing). The response carries replaced: true.
content_hashstring
Your fingerprint of the original content. Returned in listings so you can detect what changed and re-upload only that.
curl -X POST "https://www.clonify.com/api/v1/brain/sources" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{"title":"…","content":"…"}'
{
"object": "brain_source",
"id": 12438,
"source_type": "text",
"title": "Guía de sentadilla",
"word_count": 210,
"status": "ready",
"chunk_count": 3,
"replaced": false,
"created_at": "2026-07-03T17:00:00.000Z",
"updated_at": "2026-07-03T17:00:04.000Z"
}
POST/api/v1/brain/sources/link
Train the clone with a link
A web page (its clean content is extracted) or a YouTube video where ONLY the creator speaks (its transcript is used). Same pipeline and word quota as text. A video with more voices needs the original file in the panel: 422 youtube_needs_file.
Write permission
Body (JSON)
urlstring (URL)required
URL of the web page or the YouTube video.
has_other_speakersboolean
Videos only: true if someone else appears besides the creator (interview, podcast).
external_idstring
YOUR stable id for this content. If you already uploaded one with this id, it is REPLACED (idempotent upsert). Extraction runs BEFORE the replacement: a broken link doesn't destroy the previous source.
content_hashstring
Your fingerprint of the original content. Returned in listings so you can detect what changed.
curl -X POST "https://www.clonify.com/api/v1/brain/sources/link" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{"url":"…"}'
{
"object": "brain_source",
"id": 12440,
"source_type": "website",
"title": "Guía completa de la sentadilla",
"word_count": 1480,
"status": "ready",
"chunk_count": 9,
"replaced": false,
"created_at": "2026-07-05T10:00:00.000Z",
"updated_at": "2026-07-05T10:00:21.000Z"
}
POST/api/v1/brain/sources/pdf
Train the clone with a PDF
The PDF bytes in base64, up to ~3MB. Text-layer PDFs only: a scanned (image-only) one returns 422 pdf_no_text. Run OCR or send the text via POST /brain/sources. Same word quota as text.
Write permission
Body (JSON)
titlestring 2..200required
file_base64string (base64)required
The PDF bytes encoded as base64 (no data: prefix). Limit ~3MB of PDF. For bigger files, use the panel.
content_dateYYYY-MM-DD
Content date. Omit = the PDF's internal date if present. Otherwise today.
external_idstring
YOUR stable id (e.g. the file path). If you already uploaded one with this id, it is REPLACED (idempotent upsert).
curl -X POST "https://www.clonify.com/api/v1/brain/sources/pdf" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{"title":"…","file_base64":"…"}'
GET/api/v1/brain/sources/{id}
Get a source
One source with its full text (content_text). It can be heavy: listings don't carry it.
curl "https://www.clonify.com/api/v1/brain/sources/1" \
-H "Authorization: Bearer clk_live_…"
DELETE/api/v1/brain/sources/{id}
Delete a source
PERMANENTLY deletes the source, with its chunks. FREES word quota. It's the "remove and re-upload" piece for syncing content. There is no trash.
Delete permission
curl -X DELETE "https://www.clonify.com/api/v1/brain/sources/1" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{}'
{ "id": 12438, "deleted": true }
DELETE/api/v1/brain/sources
Delete a source by your id
Same as deleting by numeric id, but using YOUR external_id (the one you passed on creation): your sync doesn't need to know our ids.
Delete permission
Query parameters
external_idstringrequired
Your stable id for the source.
curl -X DELETE "https://www.clonify.com/api/v1/brain/sources" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{}'
{ "id": 12438, "external_id": "notion-doc-42", "deleted": true }
GET/api/v1/brain/folders
List knowledge folders
The folders your clone's material is organised into, with their ids. This is what you need in order to pass folder_id when you upload a source. Flat list: each folder says which one it hangs from in parent_id, and you assemble the tree. All of them come back, unpaginated.
curl "https://www.clonify.com/api/v1/brain/folders" \
-H "Authorization: Bearer clk_live_…"
{
"object": "list",
"data": [{
"object": "brain_folder",
"id": 88,
"name": "Clases del curso",
"description": null,
"parent_id": null,
"product_id": 172,
"is_course": true,
"created_at": "2026-05-02T08:12:00.000Z",
"updated_at": "2026-07-19T11:40:00.000Z"
}],
"has_more": false,
"next_starting_after": null
}
POST/api/v1/brain/folders
Create a folder
Creates a folder to file the material you upload. IDEMPOTENT: if one with that name already exists at the same level, you get the existing one back (created: false) instead of a duplicate, so a sync that runs every night doesn't fill your knowledge with copies.
Write permission
Body (JSON)
namestring 2..120required
parent_idinteger
Folder it hangs from. Omit for a top-level folder.
curl -X POST "https://www.clonify.com/api/v1/brain/folders" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{"name":"…"}'
{
"object": "brain_folder",
"id": 91,
"name": "Newsletter 2026",
"description": null,
"parent_id": null,
"product_id": null,
"is_course": false,
"created_at": "2026-07-30T10:00:00.000Z",
"updated_at": "2026-07-30T10:00:00.000Z",
"created": true
}
GET/api/v1/brain/guided-answers
List answers
The FAQs in your Knowledge (pinned first).
curl "https://www.clonify.com/api/v1/brain/guided-answers" \
-H "Authorization: Bearer clk_live_…"
POST/api/v1/brain/guided-answers
Create a answer
Two modes. WITH TEXT (with answer): the clone leans on that text faithfully when the question matches, told in its own voice and reading the conversation. FREE (no answer, with actions): the clone replies in its own voice and fires the actions. If you just want the clone to KNOW something, do not use this: add it to the knowledge with POST /brain/sources.
Write permission
Body (JSON)
questionstring 3..300required
ONE natural question, as a real visitor would write it (don't pile up several with "/").
answerstring 1..4000
The answer the clone leans on. Empty = free mode (then actions is required).
variantsstring[] (máx 10)
Other ways of asking THE SAME thing. Each one widens the semantic match.
actionsobject[]
Actions on trigger: {type: asset|product|external_link|video_embed|escalate_offer, …}.
curl -X POST "https://www.clonify.com/api/v1/brain/guided-answers" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{"question":"…"}'
DELETE/api/v1/brain/guided-answers/{id}
Delete a answer
PERMANENTLY deletes the answer, with its variants. There is no trash.
Delete permission
curl -X DELETE "https://www.clonify.com/api/v1/brain/guided-answers/1" \
-H "Authorization: Bearer clk_live_…" \
-H "Content-Type: application/json" \
-d '{}'
{ "id": 204, "deleted": true }