Concepts
SocialScope is a shared service that lets people connect a YouTube, TikTok or Instagram account to your app without your app ever seeing their password or provider tokens. Your backend then reads the account's profile, posts and metrics through one GraphQL API. This page defines the words the rest of the docs use and explains how ownership works, so you can map SocialScope onto your app's existing users and workspaces.
Who owns what
| Party | Owns |
|---|---|
| Your app backend | Its application key, its users, sessions and database, the mapping to tenant and subject, every SocialScope call |
| Your app browser | Submitting the launch form from your registered origin, landing on your return URL |
| SocialScope | The hosted Connect page, the OAuth round trip, the encrypted provider grant, token refresh, stored posts and metrics |
| The provider | The person's consent and the account itself |
| A SocialScope admin | Your client registration: origins, return URLs, tenants, providers, capabilities and keys |
Application (client)
Your app as SocialScope knows it. An admin registers it with a slug such as example-app, its exact browser origins, its return URLs, its allowed tenant keys, the providers it may use and the capabilities it may read. The admin UI calls this a client.
The application is identified by its key on every request. There is no applicationId argument anywhere in the API. Each application is isolated: a connection made through one app gives no other app access, even for the same person and the same provider account.
Tenant (tenantKey)
A workspace inside your app, such as a team, club or brand. It must be one of the tenant keys registered for your application, 1 to 128 characters. An app with no workspaces registers one tenant key and always uses it.
Subject (externalSubjectId)
Your user, as your app identifies them. It is opaque to SocialScope, 1 to 128 characters. Use your stable internal user ID, not an email address.
SocialScope does not authenticate your users. Your backend asserts which tenant and subject it is acting for, so your backend must derive both from its own authenticated session on every call and never accept them from a browser form or query string.
Scope (SubjectScope)
The pair { tenantKey, externalSubjectId }. Every connection-related operation takes a scope. SocialScope matches rows on the full tuple of application, tenant, subject and ID. A connection that belongs to another subject, tenant or application is indistinguishable from one that does not exist: you get NOT_FOUND.
Connect attempt (session)
One try at connecting one provider account. Your backend creates it with createConnectSession, the browser carries its one-use launch token to SocialScope, and the person approves at the provider. Your backend reads the outcome with connectSessionResult. An attempt has 10 minutes to finish authorization, and its result stays readable for 24 hours.
Statuses: CREATED, AUTHORIZING, EXCHANGING (in progress), then one terminal status: COMPLETED, DENIED, FAILED, EXPIRED or CANCELED. See Connect.
Connection
A provider account that a subject connected through your app. It keeps its ID across reconnects. A subject can hold several connections, including several accounts of the same provider.
Connection.status |
Meaning |
|---|---|
CONNECTED |
Active. Reads work when the capability is available, though a read can still fail if the provider registration or your app's policy changed. See Errors |
SUSPENDED |
Paused by SocialScope. In production this happens to other accounts on YouTube or TikTok while a disconnect's revoke at that provider settles. Its stored posts are dropped. Afterwards it returns to CONNECTED with a fresh scan, or moves to RECONNECT_REQUIRED |
RECONNECT_REQUIRED |
The provider grant no longer works. Start a reconnect |
DISCONNECTED |
Disconnected and being erased. It disappears once erasure finishes |
DELETING |
Reserved. Treat it like DISCONNECTED |
syncStatus is separate from status. It describes the last data sync and how to present the posts:
syncStatus |
Meaning | Show |
|---|---|---|
PENDING |
Never synced yet. Normal right after connecting | Loading |
RUNNING |
A sync job is running | Loading |
READY |
The last scan finished and was complete | Loaded |
PARTIAL |
The last scan finished but did not cover everything, for example it hit a page or item limit or could not read an item | Loaded but possibly incomplete |
STALE |
Data exists but is old, or the last job failed after an earlier success | The stored data with its age, and a refresh action |
FAILED |
The first sync failed and no data has been read yet | An error with a retry |
A COMPLETED Connect result means the account is linked. It does not mean posts are loaded.
Provider
YOUTUBE, TIKTOK or INSTAGRAM. Your app chooses the provider when it creates the attempt. The person only chooses which account to use on the provider's own consent screen.
Capability
What your app may read from a connection.
| Capability | Allows |
|---|---|
PROFILE |
Display name, handle, avatar, profile URL and description |
CONTENT_LIST |
Listing posts in a time window, scans and contentItem |
CONTENT_LOOKUP |
Looking up one post by its URL, and contentItem |
CONTENT_METRICS |
Views, likes, comments and shares on each post |
You request capabilities per attempt, and they must be a subset of what your application is allowed. The provider's consent screen asks for every permission SocialScope's provider app needs, even if you request fewer capabilities.
Observed data
SocialScope does not proxy live provider calls on each read. A background worker reads the provider and stores what it saw, stamped with observedAt. Your reads return those stored observations.
- There are no webhooks. Your app learns about changes only by polling.
- Nothing refreshes on its own after the first sync. The first sync covers the last 7 days, up to 100 posts. Call
requestRefreshwhen you need newer data. - Stored posts older than 30 days since their last observation are no longer returned by
content. A profile older than 30 days is no longer returned. - There is no metric history. Each observation replaces the previous one.
Availability
Every post, metric and capability carries an availability:
Availability |
Meaning |
|---|---|
AVAILABLE |
The value was observed and is present |
UNSUPPORTED |
The provider does not offer this value for this item, for example YouTube shares |
NOT_GRANTED |
Reserved for a value the grant does not cover |
UNAVAILABLE |
The provider omitted the value, returned something invalid, or it expired |
Only AVAILABLE carries a value. Show everything else as "not available", never as 0. A zero view count tells a creator their post flopped when SocialScope simply does not know.
Metric (MetricObservation)
One count on one post: name (VIEWS, LIKES, COMMENTS, SHARES), value (a DecimalCount), availability, reason, sourceField and observedAt.
DecimalCount is a non-negative integer sent as a string, such as "10482", so large counts never lose precision. sourceField names the provider field the value came from, because the same metric name means slightly different things per provider.
| Metric | YouTube | TikTok | |
|---|---|---|---|
VIEWS |
viewCount |
view_count |
Insight views, videos and reels only. UNSUPPORTED for images and carousels |
LIKES |
likeCount |
like_count |
like_count |
COMMENTS |
commentCount |
comment_count |
comments_count |
SHARES |
UNSUPPORTED |
share_count |
Insight shares |
Provider differences
Normalized fields do not mean identical capabilities. What a connection can return depends on the provider and the account type.
| Topic | YouTube | TikTok | |
|---|---|---|---|
| Eligible accounts | A Google account with exactly one channel | Any TikTok user | Professional accounts only (Business or Creator). Personal accounts are refused with ACCOUNT_NOT_ELIGIBLE |
| Posts listed | Uploads | Public videos only | Media, including images and carousels |
kind values |
VIDEO |
VIDEO |
VIDEO, IMAGE, CAROUSEL, UNKNOWN |
title |
Video title | Video title | Always null. The caption is in description |
thumbnailUrl |
Always null | Cover image, which expires at TikTok | Thumbnail URL. Can be null for images |
| URL lookup | Direct | Direct | Searches the 100 most recent posts only |
| Disconnect revoke | Confirmed by Google | Confirmed by TikTok | Not possible. Instagram has no revoke API, so the person must remove the app in Instagram settings |
Sync job
Asynchronous work: a scan of a time window, a metrics refresh of one post, a URL lookup, or the revoke and erase steps of a disconnect. Mutations that start work return a SyncJob, and you poll syncJob until it reaches SUCCEEDED, FAILED or CANCELED. See Reading data.
Readiness
integrationReadiness tells your app which providers it can offer right now, and whether Google sign-in is available. It reflects your app's policy and SocialScope's configuration. It does not prove a live consent will succeed.
Google identity
A separate flow that lets your app sign people up or in with Google through SocialScope. It returns verified Google identity claims once to your backend. It creates no connection, no SocialScope user and no YouTube access. See Google identity.