Data Exports
Download a portable JSON archive of your own account, and pull your live data on demand through the API and MCP.
There are two ways to get your data out of TEASE: a one-call account export that hands you a portable JSON archive of everything tied to your user, and the live API / MCP reads you already use to drive dashboards, reports, and agents. This page covers both, and flags what is on the roadmap.
Account export
One authenticated call returns a JSON file of your profile, notifications, preferences, devices, and consents.
Pull live data
Read analytics, links, attribution, inbox, and vault on demand with your
al_live_* key.
Account export (/me/export)
GET /me/export returns a downloadable JSON archive of the data tied to your own user
account. It is a self-serve GDPR-style export: every record in it belongs to you, and the
response is delivered as a file attachment so a browser saves it directly.
Authenticate with your bearer token like any other endpoint — the export always reflects the account the key belongs to, and never includes another user's data.
curl https://app.tease.link/me/export \
-H "Authorization: Bearer $TEASE_API_KEY" \
-o my-data-export.jsonimport { writeFile } from 'node:fs/promises';
const res = await fetch('https://app.tease.link/me/export', {
headers: { Authorization: `Bearer ${process.env.TEASE_API_KEY}` },
});
await writeFile('my-data-export.json', Buffer.from(await res.arrayBuffer()));import os, requests
res = requests.get(
"https://app.tease.link/me/export",
headers={"Authorization": f"Bearer {os.environ['TEASE_API_KEY']}"},
)
with open("my-data-export.json", "wb") as f:
f.write(res.content)The response is served with Content-Type: application/json and a
Content-Disposition: attachment; filename="my-data-export.json" header, so it downloads as a
file rather than rendering inline.
What the archive contains
The export is a single JSON object with a top-level exported_at timestamp and the following
sections:
| Section | Type | Description |
|---|---|---|
profile | object | Your account identity: id, email and verification state, first name, linked Telegram id/username, account creation time, and last login. |
notifications | array | Your in-app notification history — each with a timestamp, category, title and body, optional link, level, and when it was read. |
notification_preferences | array | Your per-category, per-channel notification settings (which categories are enabled on which channels). |
devices | array | Devices seen on your account — each with an opaque device label, plus first-seen and last-seen. |
consents | array | Your consent records — each with a kind, whether it was granted, and a timestamp. |
not_included | array | A plain-language list of data categories deliberately left out of this export (see below), so the archive is honest about its scope. |
Privacy by design
Device rows carry only an opaque label and first/last-seen timestamps. Secrets, password material, and connection credentials are never part of an export, even your own.
Example response
{
"exported_at": "2026-07-01T12:00:00Z",
"profile": {
"id": 12,
"email": "creator@example.com",
"email_verified": true,
"email_verified_at": "2026-05-02T09:14:00Z",
"first_name": "Alex",
"telegram_id": 583920114,
"telegram_username": "alexcreator",
"created_at": "2026-04-28T18:02:00Z",
"last_login_at": "2026-07-01T08:41:00Z"
},
"notifications": [
{
"ts": "2026-06-30T20:15:00Z",
"category": "payout",
"title_ru": "Выплата отправлена",
"body_ru": "Ваша выплата за июнь отправлена.",
"link": "/payouts",
"level": "info",
"read_at": "2026-06-30T21:02:00Z"
}
],
"notification_preferences": [
{ "category": "payout", "channel": "email", "enabled": true },
{ "category": "marketing", "channel": "email", "enabled": false }
],
"devices": [
{
"device_label": "MacBook — Chrome",
"first_seen": "2026-04-28T18:02:00Z",
"last_seen": "2026-07-01T08:41:00Z"
}
],
"consents": [
{ "kind": "tos", "granted": true, "ts": "2026-04-28T18:02:00Z" },
{ "kind": "marketing_email", "granted": false, "ts": "2026-05-10T11:30:00Z" }
],
"not_included": [
"OnlyFans connection credentials and vaulted secrets",
"Funnel analytics (clicks / impressions) — aggregate, not keyed to your account",
"Billing/payment provider records",
"Server logs and outbound notification delivery records"
]
}What is not in the export
The export is your account data. It deliberately leaves out categories that live in other
subsystems or are platform-global, and lists them under not_included so nothing is silently
omitted:
- OnlyFans connection credentials and vaulted secrets.
- Funnel analytics (clicks / impressions) — these are aggregate and not keyed to your account.
- Billing / payment-provider records.
- Server logs and outbound notification delivery records.
For your business data — link performance, attribution, fans, chat, vault — use the live reads below.
Pull live data via the API
Every analytics and resource read in the TEASE API returns JSON and is scoped to the owner the
key belongs to, so you can export exactly what you need into your own warehouse, spreadsheet,
or BI tool on a schedule. A read-only al_live_* key is all you need.
| Data you want | Endpoint | Returns |
|---|---|---|
| Smart-link performance | GET /api/admin/smart-links | Every link with its click → subscriber → revenue rollup. |
| Single-link drill | GET /api/admin/smart-links/{provider_id} | Clicks, subscribers, spenders, revenue, and ARPS for one link. |
| CTR / click funnel | GET /api/admin/stats | Click-funnel and CTR metrics across your links. |
| Attribution leaderboard | GET /api/admin/stats | Revenue-by-source (attributed / organic / pending), country/link/fan drills, and fan economics. |
| Per-link geo/source breakdown | GET /api/admin/domain_links/smartlinks/breakdown | Per-link geography and source split. |
| Inbox conversations | GET /api/admin/inbox/conversations | Your DM threads (waiting-first, no stored message bodies). |
| Vault search | GET /api/admin/vault/search | Vault media_ids matching a title/tag query. |
| Content performance | GET /api/admin/vault/performance | Top media and tags by revenue and unlock rate. |
A simple nightly pull looks like this:
curl https://app.tease.link/api/admin/stats \
-H "Authorization: Bearer $TEASE_API_KEY" \
-o tease-stats-$(date +%F).jsonMint a dedicated read-only key for any export or reporting job. It can pull every read in the table above but can never mutate state. See Authentication for scopes.
See the full request and response shapes in the API Reference, and the attribution payloads in Attribution.
Pull data via MCP
If you drive TEASE from an AI agent or an automation tool, the same reads are available as
MCP tools over the JSON-RPC endpoint at POST /mcp, authenticated with your al_live_*
key. An agent can call a read tool, receive structured JSON, and write it wherever you point
it — no glue code on your side.
Point your MCP client at https://app.tease.link/mcp and pass your key as a Bearer token.
Call tools/list to discover the available read tools and their input schemas.
Call tools/call with the read tool you want; the result comes back as JSON you can
persist or transform.
See AI & MCP for the connection details, the full tool catalog, and scope behavior.
Shared analytics reports (Telegram channel)
The «Канал» dashboard ships a one-click, branded shareable report. The share link
(https://app.tease.link/exports/<token>) opens an interactive report page built from
the dashboard's own components — same design, clickable cards, post drill-down popups — on
both mobile and desktop. The PDF is an exact print of that very page (clickable links,
branded footer on every page). Both are frozen snapshots: numbers never change after
you shared them.
- Preview & checkboxes. «Скачать аналитику» opens a dialog: on the left — the REAL report blocks exactly as the recipient will see them, live-updating as you toggle section checkboxes on the right. Two presets: advertiser-safe (default — no revenue, no ROI, no raw invite URLs) and full report. Money fields appear only when you explicitly switch «Финансы» on. Exporting is owner-only — team members don't get the button or the endpoints.
- Password. An optional password gates the report page and its data, and encrypts the PDF itself (AES-256; every modern viewer opens it).
- Delivery. Download the PDF, copy the share link, send the PDF to your linked Telegram as a document (with the interactive link in the caption), or email the link. Each share tracks views and downloads, and can be revoked at any time — the page, data, media and file all turn into a uniform 404.
- AI-readable. The share serves machine-readable JSON:
?format=jsonon the PDF URL (compact analytics twin) — password-protected shares require theX-Export-Passwordheader. Feed it to Claude or any AI assistant — no OCR, no scraping. - MCP. Agents can mint the same report with the
export_tg_channel_pdftool (awrite-scope key is required, since it creates a public link) and use the returnedurl(interactive page),pdf_urlandjson_url.
Event journal (history export & retention)
Behind every number in the dashboard is an append-only event journal: one row per fact — a fan subscribed, a payment cleared, a message went out. Reports are rebuilt from these rows, which is why they can be recomputed after the fact instead of being frozen at write time.
Journal rows are kept for 90 days
Events older than 90 days are deleted. Take an export before you need it — a deleted row cannot be restored. Daily snapshots keep the state (who is subscribed, what they paid) intact past that horizon; the step-by-step history is what expires.
What you can pull
| Endpoint | Returns |
|---|---|
GET /api/admin/journal/summary | How many rows you hold, the oldest date, and how many are already past the retention horizon. |
GET /api/admin/journal/export?since=&until= | The events themselves as newline-delimited JSON (.jsonl), one object per line. since / until are unix seconds; omit for "no bound". |
GET /api/admin/journal/snapshot?entity=fans | The latest daily snapshot — state on a date — as one JSON file. |
# everything from the last 30 days
curl "https://app.tease.link/api/admin/journal/export?since=$(( $(date +%s) - 2592000 ))" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-o journal-export.jsonlEach line is self-describing, so the file stays readable without our code:
{"seq":4711,"type":"fan.subscribed","version":1,"entity_type":"fan","entity_id":"88213",
"account_id":"acc_1","occurred_at":1795000000,"recorded_at":1795000042,"source":"poll",
"payload":{"fan_id":"88213","sub_price_cents":999,"current_action":"subscribe"}}The export is scoped to your own tenant and runs through the same bulk-export guard as the
other downloads on this page — a daily row quota, plus a second factor if your account has one.
A period that would exceed the per-request cap is refused with period_too_wide rather than
silently truncated: a short file that looks complete is worse than an honest error.
What is never deleted
Event types that no projection rebuilds yet — payments, for example, until the money
projection ships — are kept without a time limit, no matter how old. Deleting them would
mean losing history that nothing can reconstruct. GET /api/admin/journal/summary lists them
under kept_forever.
Bulk file exports (roadmap)
Roadmap
Self-serve bulk file exports — one-click CSV / XLSX downloads of transactions, fans, and messages — are on the roadmap and not available today. Until they ship, use the account export above for your own account data, and the live API / MCP reads for business data.
Planned bulk exports include:
- Transactions — a flat ledger of subscriptions, rebills, tips, and PPV unlocks.
- Fans — your subscriber list with lifecycle and value attributes.
- Messages — campaign and conversation history.
These will be offered as both dashboard downloads and a two-step API (request an export job, then fetch the file), matching how the rest of the API behaves. This page will document the endpoints, field tables, and formats when the feature is released.
FAQ
Next steps
- Authentication — mint a scoped
al_live_*key. - API Reference — every read endpoint and its response shape.
- AI & MCP — pull the same data from an agent.