# Creator vet report

`GET https://api.onekey.dev/v1/reports/creator-vet?handle=...` looks up one handle on several platforms and gives what those platforms say about it: profile numbers, how often the account posts, and how its recent posts performed. It uses no AI. See [Reports](https://onekey.dev/docs/reports.md) for the shape and rules every report shares.

> [!WARN] **No authenticity or quality score is computed, anywhere in the answer.** Every number is a platform field or the published [engagement](https://onekey.dev/docs/computed.md) and cadence arithmetic. The report will not tell you whether an account is real, or good. It tells you what the platforms report and where they report nothing.

```bash
curl "https://api.onekey.dev/v1/reports/creator-vet?handle=torvalds&platforms=github,bluesky" \
  -H "x-api-key: YOUR_API_KEY"
```

## Inputs

| Parameter | Values | What it does |
| --- | --- | --- |
| `handle` | text, required, up to 200 characters | The account handle or username, sent as-is to each platform. |
| `platforms` | comma list | Vet the handle on exactly these. Each needs a profile endpoint. Default: every platform with one (17 today: Bluesky, crates.io, DEV Community, GitHub, GitLab, Hacker News, Huggingface, Instagram, Lemmy, Lobsters, Mastodon, Reddit, SoundCloud, TikTok, Twitch, X (Twitter), YouTube), cut to `max_platforms`. |
| `max_platforms` | 1 to 12, default 6 | Cap on the platform list. |
| `dry_run` | `true` | See [Dry run](https://onekey.dev/docs/reports.md#dry-run). |

There are no AI parameters. `include`, `label`, `relevance` and `themes` are refused with [`INVALID_PARAMS`](https://onekey.dev/docs/errors.md#invalid-params).

The same handle is not the same account on every platform. A handle that does not exist on a platform is a `404` leg with its own row, and the report says so instead of inventing an answer.

## What each platform section contains

Each platform in `data.platforms` has:

| Field | Meaning |
| --- | --- |
| `profile` | `{username, id, url, bio}` from the platform's profile endpoint. `null` if the profile leg failed. |
| `followers`, `following`, `verified` | The platform's own `author.*` fields. `null` with a `_warnings` entry when a platform does not provide one. |
| `cadence` | How often the account posts (below). `null` when there is no feed or too few dated posts. |
| `recent_engagement` | Mean likes, comments and shares over the sampled posts, and the mean `engagement_rate`. |
| `cadence_source` | The feed endpoint used, or `null` when the platform has no per-user feed. |
| `_warnings` | One line for every missing or failed part. |

`data.summary` adds `platforms_answered`, `followers_by_platform`, `followers_total` (over the platforms that reported a number) and `followers_known_on` (how many that is), so a total can never look more complete than it is.

### Cadence

`posts_per_week = (dated posts - 1) / span between the oldest and the newest dated post, in weeks`, over the first page of the account's feed. The block also carries `posts_sampled`, `posts_dated`, `span_days`, `newest` and `oldest`. It is the mean interval of that sample, nothing more: it is not a forecast and not a posting schedule. It is `null`, with a warning, under 2 dated posts or when they share one timestamp. Example from the report's own tests: 5 posts over 12 days is 2.33 posts a week.

Cadence uses the first page only of the feed (10 to 25 posts). A feed that includes reposts counts them: the Bluesky posts feed is one.

### Which platforms have a cadence feed

Only these eight:

| Platform | Feed | Status and price |
| --- | --- | --- |
| Bluesky | [`bluesky.posts`](https://onekey.dev/docs/api/bluesky/posts.md) | stable, 1 credits |
| DEV Community | [`devto.articles_by_user`](https://onekey.dev/docs/api/devto/articles_by_user.md) | stable, 5 credits |
| Hacker News | [`hackernews.author_submissions`](https://onekey.dev/docs/api/hackernews/author_submissions.md) | stable, 5 credits |
| Instagram | [`instagram.posts`](https://onekey.dev/docs/api/instagram/posts.md) | beta, 2 credits |
| Lobsters | [`lobsters.user_stories`](https://onekey.dev/docs/api/lobsters/user_stories.md) | stable, 5 credits |
| Reddit | [`reddit.user_posts`](https://onekey.dev/docs/api/reddit/user_posts.md) | beta, 2 credits |
| Twitch | [`twitch.videos`](https://onekey.dev/docs/api/twitch/videos.md) | stable, 1 credits |
| X (Twitter) | [`x.user_tweets`](https://onekey.dev/docs/api/x/user_tweets.md) | stable, 2 credits |

Every other platform, including GitHub, GitLab, crates.io, Hugging Face, Lemmy, Mastodon (its feed needs an id, not a handle), SoundCloud, TikTok and YouTube, gives its profile numbers only, and `cadence` and `recent_engagement` are `null` with a warning. Instagram and Twitch feeds are beta.

### Recent engagement and the fallback

`recent_engagement` averages likes, comments and shares over the sampled posts, plus the mean `engagement_rate` of those posts, computed by the [published formula](https://onekey.dev/docs/computed.md).

**`engagement_rate` is often `null`.** It needs a divisor: the post's own views, or a follower count for its author. Many feeds carry neither. The fallback is the follower count from the profile leg: a post without a divisor of its own uses the profile's follower count, and `divisor` says which was used (`views`, `post_author_followers` or `profile_followers`). If the profile leg failed, or the platform reports no followers, there is no divisor and the rate stays `null`. The means of likes, comments and shares are still there. In the test fixture, 5 posts with a mean of 30 likes and 2,000 followers from the profile give `engagement_rate_avg: 1.65` with `divisor: ["profile_followers"]`.

## A recorded call

Recorded on the dev API, shortened. Some platforms answer and some do not, and the report says which:

```bash
curl "https://api.onekey.dev/v1/reports/creator-vet?handle=torvalds&platforms=github,reddit,hackernews,bluesky" \
  -H "x-api-key: YOUR_API_KEY"
```

```json
{
  "success": true,
  "data": {
    "report": "creator_vet",
    "methodology_version": "creator_vet/1",
    "inputs": {
      "handle": "torvalds", "platforms": ["github", "reddit", "hackernews", "bluesky"], "selection": "explicit",
      "cadence_sources": { "github": null, "reddit": "reddit.user_posts", "hackernews": "hackernews.author_submissions", "bluesky": "bluesky.posts" }
    },
    "legs": ["...7 rows: github.profile 200, reddit.user_about 502, reddit.user_posts 502, hackernews.user 404, hackernews.author_submissions 200 (empty), bluesky.profile 502, bluesky.posts 502"],
    "coverage": {
      "answered": ["github", "hackernews"],
      "failed": [
        { "platform": "reddit", "endpoint": "user_about", "status": 502, "type": "UPSTREAM_BLOCKED" },
        { "platform": "hackernews", "endpoint": "user", "status": 404, "type": "NOT_FOUND" },
        { "platform": "bluesky", "endpoint": "profile", "status": 502, "type": "UPSTREAM_ERROR" }
      ],
      "missing_fields": {}
    },
    "platforms": [
      {
        "platform": "github",
        "profile": { "username": "torvalds", "id": "1024025", "url": "https://github.com/torvalds", "bio": null },
        "followers": 325719, "following": 0, "verified": null,
        "cadence": null, "recent_engagement": null, "cadence_source": null,
        "_warnings": ["github does not provide author.verified", "no recent-posts endpoint on github: cadence and recent_engagement are null"]
      },
      {
        "platform": "hackernews", "profile": null, "followers": null, "cadence": null, "recent_engagement": null,
        "cadence_source": "hackernews.author_submissions",
        "_warnings": ["profile leg failed: NOT_FOUND", "cadence needs at least 2 dated posts; got 0 of 0"]
      }
    ],
    "summary": {
      "platforms_answered": 1,
      "followers_by_platform": { "github": 325719, "reddit": null, "hackernews": null, "bluesky": null },
      "followers_total": 325719,
      "followers_known_on": 1,
      "note": "No authenticity or quality score is computed: every number above is a platform field or the published engagement / cadence arithmetic"
    },
    "ai_methodology_version": null,
    "credits": { "legs": 6.0, "ai": 0.0, "total": 6.0 }
  },
  "metadata": { "recipe": "creator_vet", "credits_charged": 6.0 }
}
```

How to read it: this network could not reach two of the platforms, the handle `torvalds` has no Hacker News account and is not a Bluesky handle, and the report says so leg by leg. Only the legs that answered were charged (6 credits). GitHub has no feed, so its cadence is `null` and stays that way.

## Costs

The legs at their own prices, nothing more: no AI, no surcharge. A dry run for the handle on GitHub and Bluesky, recorded:

```json
{
  "data": {
    "report": "creator_vet",
    "legs": [
      { "platform": "github", "endpoint": "github.profile", "params": { "username": "torvalds" }, "credits": 1.0, "worst_case_credits": 3.0 },
      { "platform": "bluesky", "endpoint": "bluesky.profile", "params": { "handle": "torvalds" }, "credits": 1.0, "worst_case_credits": 1.0 },
      { "platform": "bluesky", "endpoint": "bluesky.posts", "params": { "handle": "torvalds" }, "credits": 1.0, "worst_case_credits": 1.0 }
    ],
    "credits": { "legs_worst_case": 5.0, "legs_list_price": 3.0, "ai": null }
  },
  "metadata": { "recipe": "creator_vet", "dry_run": true, "legs": 3, "credits_charged": 0.0 }
}
```

Each platform with a feed costs a profile leg plus a feed leg. Vetting on more platforms costs more, so name the platforms you need with `platforms` rather than relying on the default pool.

## Limits

- **No authenticity or quality score.** None is computed.
- **Cadence feeds exist for the eight platforms above only.** Others return profile numbers and nulls.
- **Cadence is the first page of a feed** (10 to 25 posts), and includes reposts where the feed does.
- **`engagement_rate` is often `null`**, with the profile follower count as the fallback divisor.
- **A handle is not an identity.** The report does not check that the accounts on different platforms belong to the same person.
- Reports are JSON only. A `Accept: text/event-stream` header is ignored, and a report is not yet a target for a [monitor](https://onekey.dev/docs/monitors.md).
