# ModelVI — Agent Skill (`agents.modelvi.com/skill.md`)

> One file with everything an AI agent needs to post & schedule content across **14 creator platforms**
> through one API. Give your agent this file + an API key and it can run a whole creator operation.
>
> **Status legend:** ✅ live · 🔜 shipping (self-serve productization layer).

## What is ModelVI?
ModelVI automates posting for adult-creator agencies. One agency manages **models**, each model has
**platform-accounts** (Fansly, F2F, FanCentro, Fanvue, Maloum, OnlyFans, KNKY, LoyalFans, BestFans,
Fourbased, MYMfans, FetLife, Fansyme, Brezzels), and you **schedule posts** that the ModelVI engine
publishes to those accounts on time. The Partner API exposes this so your own agent/tooling can drive it.

## Base URL & Auth ✅
- **Base URL:** `https://modelvi.com/api/partner/v1`
- **Auth:** `Authorization: Bearer mvk_<keyId>_<secret>`  (alternative: header `X-Partner-Key: mvk_...`)
- **Key format:** `mvk_<keyId>_<secret>`.
- **Get a key:** 🔜 self-serve in the dashboard (any agency → *API Keys → Create key*, scope = your own
  models/accounts). Whitelabel partners get a reseller-scoped key (their own + their clients) + bulk pricing.
- **Public probe (no key):** `GET /version` → `{"success":true,"version":"partner api version 1.0"}`.
- The OpenAPI spec is available to authenticated partners; it is **not** public.

## Response shape ✅
Every 2xx wraps in an envelope: `{ "success": true, "payload": <data> }`. Errors return `success:false`
with a message (and the HTTP status). Handle `429` (rate limit) via the `Retry-After` header.

## Rate limits ✅
- **600 requests/min per API key** · **120 requests/min per source IP** (stricter, pre-auth).
- Sliding 60s window · exceed → **HTTP 429 + `Retry-After`**. These are fixed global caps, not per-partner.

## Core endpoints ✅
| Area | Method + path | Purpose |
|---|---|---|
| Version | `GET /version` | public liveness probe |
| Models | `GET /model_list` | list your models |
| Accounts | `GET /account_list` | list platform-accounts |
| Accounts | `GET/POST/PUT/DELETE /account/{platform}` · `PUT/DELETE /account/{platform}/{accountId}` | manage accounts |
| Content | media upload endpoint (returns the media `name` you reference in a post) | upload media |
| Schedule | `GET /schedule` (list) · `POST /schedule` (create) | scheduled posts |
| Schedule | `PUT /schedule/{scheduleId}` · `DELETE /schedule/{scheduleId}` | edit/cancel |
| Results | `GET /schedule_result` · `GET /schedule_result/{resultId}` | per-account publish status |

## Create a scheduled post — the real body ✅
`POST /schedule`
**Platform CODES** (use these exact codes in `platforms` and the `{platform}` path — NOT the display names):
`F2F` `FNC`(FanCentro) `FAN`(Fansly) `KNKY` `MALOUM` `ONLYFANS` `LOYALFANS` `MYMFANS` `FETLIFE`
`FOURBASED` `FANVUE` `BESTFANS` `FANSYME` `BREZZELS`. ⚠️ e.g. Fansly = `FAN` (not `FANSLY`), FanCentro = `FNC`.

```json
{
  "model": "<modelId>",
  "platforms": ["FAN", "F2F"],
  "medias": [{ "name": "<uploaded-media-key>", "mode": "image/jpeg", "size": 12345 }],
  "title": "your caption here",
  "scheduledAt": "2026-07-21T14:00:00Z",
  "type": 1,
  "price": 0,
  "tags": ["tag1"],
  "folder": "Posts"
}
```
- **`model`, `platforms`, `medias`, and `scheduledAt` are REQUIRED** — a schedule targets a model across 1+ platforms (not a single account), with at least one media and a scheduled time.
- **`title`** = the caption (NOT `caption`). **`scheduledAt`** = camelCase ISO, minute precision, UTC (NOT `scheduled_at`).
- **`medias`** = array of `{name, mode, size}`; `name` is a key returned by the upload endpoint.
- **`type`**: `1` = FREE, `2` = FANS (subscribers), `3` = PAID (PPV, set `price`).
- ⚠️ Use only captions/tags the model's manager set in the vault — content must read human, never bot/test text.

## Typical agent flow
1. `GET /model_list` → pick a model + note its platforms via `GET /account_list`.
2. Upload media → get the media `name`.
3. `POST /schedule` with the body above.
4. `GET /schedule_result/{resultId}` → confirm it published per account.

## Productization layer (🔜, for the public product)
- **`agents.modelvi.com/skill.md`** — this file, publicly hosted (self-describing for any agent).
- **"Connect your agent" UI** — dashboard page: create a key + copy the endpoint + this skill.md link.
- **MCP server** (`mcp.modelvi.com`; whitelabel `agents.<partner>.com`) — wraps these endpoints as MCP
  tools (generated from the OpenAPI spec) so an agent can call them as native tools. Same engine, same
  scope-by-key. (Phase 2 — the REST API + this skill.md already work without it.)
- **Pricing:** normal self-serve tier · whitelabel = bulk discount (requestable).
