One schema for every platform

Platforms name the same idea differently. Onekey maps every source onto one fixed set of field names, gives you null when a source does not have a field, and keeps platform-specific data under ext.*.

From raw paths to one shape

Three platforms, three ways of saying who wrote a post and how it did. These are the real source paths from our endpoint specs.

raw field paths to one post shape
Reddit sends
Bluesky sends
Mastodon sends
You get
Redditdata.children.0.data.authorBlueskythread.post.author.handleMastodonaccount.usernameauthor.username
Redditnot providedBlueskythread.post.author.displayNameMastodonaccount.display_nameauthor.displayName
Redditdata.children.0.data.selftextBlueskythread.post.record.textMastodoncontentcontent.text
Redditdata.children.0.data.created_utcBlueskythread.post.record.createdAtMastodoncreated_atcontent.createdAt
Redditdata.children.0.data.scoreBlueskythread.post.likeCountMastodonfavourites_countengagement.likes
Redditdata.children.0.data.num_commentsBlueskythread.post.replyCountMastodonreplies_countengagement.comments

Paths are read from the endpoint specs at build time (reddit.post, bluesky.post_thread, mastodon.status). Same keys whatever the platform; a field it does not provide is null, never missing. Every field is in the schema reference.

Before and after

Two platforms, the same idea. Left is the source's own shape from a recorded response, trimmed to the fields the mapping reads; right is what you get back.

Bluesky bluesky.profile, 1 credit. 8 fields shown of the recorded response.

Source shape what the platform sends

{
  "did": "did:plc:z72i7hdynmk6r22z27h6tvur",
  "handle": "bsky.app",
  "displayName": "Bluesky",
  "followersCount": 35077323,
  "followsCount": 15,
  "postsCount": 864,
  "description": "official Bluesky account (check username👆)\n\nBugs, feature …",
  "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r…"
}

Onekey data in the response

{
  "author": {
    "id": "did:plc:z72i7hdynmk6r22z27h6tvur",
    "username": "bsky.app",
    "displayName": "Bluesky",
    "followers": 35077323,
    "following": 15,
    "avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r…"
  },
  "engagement": {
    "comments": 864
  },
  "content": {
    "text": "official Bluesky account (check username👆)\n\nBugs, feature …"
  }
}

YouTube youtube.channel, 2 credits. 8 fields shown of the recorded response.

Source shape what the platform sends

{
  "id": "UCuAXFkgsw1L7xaCfnd5JJOw",
  "snippet": {
    "title": "Rick Astley",
    "description": "Official channel",
    "customUrl": "@rickastley",
    "thumbnails": {
      "default": {
        "url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg"
      }
    }
  },
  "statistics": {
    "subscriberCount": "4200000",
    "viewCount": "3000000000",
    "videoCount": "180"
  }
}

Onekey data in the response

{
  "author": {
    "id": "UCuAXFkgsw1L7xaCfnd5JJOw",
    "displayName": "Rick Astley",
    "bio": "Official channel",
    "username": "@rickastley",
    "avatarUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg",
    "followers": 4200000
  },
  "engagement": {
    "views": 3000000000
  },
  "ext": {
    "videos": 180
  }
}

Same names on every platform#

Platforms name the same idea differently: a follower count is followersCount on one and statistics.subscriberCount on another. Onekey maps every source onto one fixed schema of 147 fields (version 1.0), grouped by what they describe: author, content, engagement, entity, media, market, place, listing, package, paper and event. You write your parsing once.

The field list is read from the same definition the backend enforces, and the counts of which endpoints return each field come from the field mappings of the 1,995 endpoints, so they cannot drift from what the API serves.

The rules that make it trustworthy#

Where to look#