@sprid/cli 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENSE +14 -0
- package/README-post.md +615 -0
- package/README.md +249 -0
- package/SECURITY.md +18 -0
- package/bin.mjs +12 -0
- package/package.json +47 -0
- package/src/args.mjs +134 -0
- package/src/browser.mjs +28 -0
- package/src/cli.mjs +257 -0
- package/src/commands/auth.mjs +192 -0
- package/src/commands/completion.mjs +90 -0
- package/src/commands/connect.mjs +586 -0
- package/src/commands/docs.mjs +53 -0
- package/src/commands/family.mjs +96 -0
- package/src/commands/init.mjs +137 -0
- package/src/commands/local-tools.mjs +31 -0
- package/src/commands/marketing-review.mjs +106 -0
- package/src/commands/mcp.mjs +53 -0
- package/src/commands/misc.mjs +94 -0
- package/src/commands/pinterest.mjs +120 -0
- package/src/commands/plan.mjs +230 -0
- package/src/commands/post.mjs +41 -0
- package/src/commands/reviews.mjs +149 -0
- package/src/commands/setup.mjs +220 -0
- package/src/commands/status.mjs +217 -0
- package/src/commands/studio.mjs +69 -0
- package/src/commands/update.mjs +69 -0
- package/src/creds.mjs +126 -0
- package/src/docs/commands.mjs +152 -0
- package/src/docs/guides.generated.mjs +1178 -0
- package/src/docs/help.mjs +77 -0
- package/src/docs/index.d.mts +18 -0
- package/src/docs/index.mjs +45 -0
- package/src/docs/queries.d.mts +11 -0
- package/src/docs/queries.mjs +77 -0
- package/src/endpoint.mjs +17 -0
- package/src/evidence.mjs +15 -0
- package/src/format.mjs +71 -0
- package/src/http.mjs +117 -0
- package/src/pending.mjs +27 -0
- package/src/post/cli.mjs +2285 -0
- package/src/post/json-worker.mjs +12 -0
- package/src/post/preview-server.mjs +58 -0
- package/src/post/preview.mjs +660 -0
- package/src/post/recipes/screen.mjs +290 -0
- package/src/post/recipes/stills.mjs +146 -0
- package/src/post/rules/platform-rules.d.mts +27 -0
- package/src/post/rules/platform-rules.mjs +164 -0
- package/src/post/screen/captions.mjs +131 -0
- package/src/post/screen/compose.mjs +284 -0
- package/src/post/screen/input.mjs +163 -0
- package/src/post/screen/sim.mjs +443 -0
- package/src/post/screen/simkit.swift +328 -0
- package/src/profiles.mjs +61 -0
- package/src/release.ts +2 -0
- package/src/screenshots.ts +1 -0
- package/src/updates.mjs +152 -0
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
// Generated by scripts/build-docs.mjs. Edit plugin guides, then run bun run docs:build.
|
|
2
|
+
export const GUIDE_GROUPS = [
|
|
3
|
+
{
|
|
4
|
+
"title": "Account setup",
|
|
5
|
+
"slugs": [
|
|
6
|
+
"social-accounts"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"title": "Stores and analytics",
|
|
11
|
+
"slugs": [
|
|
12
|
+
"app-store-connect",
|
|
13
|
+
"google-play",
|
|
14
|
+
"search-console",
|
|
15
|
+
"posthog",
|
|
16
|
+
"revenuecat",
|
|
17
|
+
"stripe",
|
|
18
|
+
"polar",
|
|
19
|
+
"lemonsqueezy",
|
|
20
|
+
"paddle",
|
|
21
|
+
"cloudflare"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"title": "Publishing channels",
|
|
26
|
+
"slugs": [
|
|
27
|
+
"instagram",
|
|
28
|
+
"tiktok",
|
|
29
|
+
"youtube",
|
|
30
|
+
"linkedin",
|
|
31
|
+
"facebook",
|
|
32
|
+
"x",
|
|
33
|
+
"pinterest"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
export const GUIDE_ALIASES = {
|
|
38
|
+
"asc": "app-store-connect",
|
|
39
|
+
"play": "google-play",
|
|
40
|
+
"gsc": "search-console"
|
|
41
|
+
};
|
|
42
|
+
export const METRIC_EVIDENCE = "# Metric evidence\n\nSprid’s review packet includes a versioned `dataset`: observations, checked results and hashes of the source receipts. The CLI saves complete review/query packets under `marketing-reports/evidence/` with immutable content-hash filenames and owner-only file permissions. The plugin runner preserves that dataset alongside its local evidence and git context. An explicit runner `--output` refuses to overwrite an existing file.\n\n## Read a number\n\n- `definition` names the entity, measurement kind, unit, calculation basis and implementation version. An active subscription is not a unique customer; a store download is not an activated person.\n- `window` uses an exclusive end and retains its calendar. `asOf` belongs to a snapshot; `fetchedAt` records collection. Historical revenue and current MRR are separate observations.\n- `quality` separates coverage, pagination, sampling, finality and trust. A successful HTTP request does not prove complete coverage. Unknown, pending, suppressed and unavailable values remain missing.\n- `value.kind: money` stores an exact decimal coefficient and scale with a currency and conversion policy. Do not assume every provider amount is cents. Keep gross, refunded revenue and proceeds separate.\n\n## Respond to a blocked calculation\n\n| Reason | Continue with |\n| --- | --- |\n| `currency_mismatch` | Separate currency rows; convert only with explicit dated FX evidence and a declared policy. |\n| `overlap_unresolved` | Source subtotals and the identity check. Do not add RevenueCat and a rail it already ingests. |\n| `definition_mismatch` | Name the provider definitions separately, including MRR policy and revenue basis. |\n| `window_mismatch` | Request matching periods/calendars. A daily Pacific aggregate cannot be relabeled UTC. |\n| `population_mismatch` | Verify numerator/denominator attribution with an actual identity mapping. All-app revenue cannot stand for website-cohort revenue. |\n| `incomplete_sources`, `incomplete_coverage` | Keep usable readings; complete pagination or narrow the period. Missing dates are not automatically zero. |\n| `unverified_calculation` | Inspect emitting code and the query’s population, ordering and exclusions. Preserve a local attestation for local database work. |\n| `non_additive` | Query period-level distinct people, select the relevant snapshot, or recompute a rate from compatible numerators and denominators. |\n\n## Investigate through Sprid\n\nRun `sprid marketing-review capabilities --app <slug>` to discover operations. The `revenuecat` / `revenue` operation reads an explicit period total, with `revenue_type` set to `revenue`, `revenue_net_of_taxes` or `proceeds`. Its scope is the bound RevenueCat project, which can contain multiple apps. Use `chart_options` before selecting chart dimensions. Cohort-chart period zero may describe customer count, not the month-zero metric.\n\nCustom query results carry `measurement` provenance and retain provider-native data. They remain investigative; the server does not certify arbitrary SQL’s business meaning. The shared calculation library supports sequential/strict ordered funnels and fixed elapsed-time retention from complete event evidence. These helpers are not additional public query operation names. For provider-side investigations, use the discovered custom query operation and preserve the exact SQL.\n\nStripe MRR is a current active/past-due price estimate before discounts. Paddle’s adapter reports gross completed transactions before adjustments. Lemon Squeezy combines orders with renewal/update invoices and excludes duplicate initial invoices; a complete priced schedule is required for MRR. Separate source readings survive when combined totals cannot be justified.\n\nRevenue observations and aggregate Search Console observations are normalized in the review dataset. Other source receipts retain native definitions and coverage; they are not silently converted into a universal business scorecard. App-specific activation, cross-source identity and attribution still require repository evidence. Local fallback results do not automatically inherit the server dataset’s verification.\n\nSave the full packet and exact query beside the report. Hashes identify evidence but cannot recreate it. Link corrected reports to their earlier dataset and retain the earlier packet; provider backfills and refund revisions must remain inspectable. Sprid does not upload repository database rows or provide hosted dataset-history storage through this contract.\n";
|
|
43
|
+
export const GUIDES = [
|
|
44
|
+
{
|
|
45
|
+
"id": "social-accounts",
|
|
46
|
+
"title": "Create your social accounts",
|
|
47
|
+
"summary": "Connect your brand, creator and other social accounts to their own publishing destinations, so approved content reaches the intended audience.",
|
|
48
|
+
"command": "sprid connect instagram --account yourbrand",
|
|
49
|
+
"url": "https://sprid.studio/docs/connect/social-accounts",
|
|
50
|
+
"sections": [
|
|
51
|
+
{
|
|
52
|
+
"id": "you-need",
|
|
53
|
+
"title": "You need",
|
|
54
|
+
"kind": "requirements",
|
|
55
|
+
"markdown": "- The email address that should own the accounts, access to its inbox, and your phone for verification.\n- Your chosen account names, handles and the purpose of each account. Handles are proposals until the platform confirms them.\n- Access to your existing Meta business portfolio if it should own the Facebook Pages and Instagram accounts.\n\nKeep passwords, verification codes and identity documents in the platform’s own browser or app. An agent can prepare forms and continue after you sign in."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "set-up-your-account-map",
|
|
59
|
+
"title": "Set up your account map",
|
|
60
|
+
"kind": "steps",
|
|
61
|
+
"markdown": "You can connect one main account or several accounts with different purposes. A side account might share educational content, follow a character or cover a topic separately from your main brand.\n\n| Account purpose | Example display name | Example handle | Sprid publishing account |\n|---|---|---|---|\n| Main brand or product | Your Brand | yourbrand | yourbrand |\n| Founder or creator | Alex from Your Brand | alexfromyourbrand | brand-founder |\n| Character or persona | Everyday Alex | everydayalex | everyday-alex |\n| Topic or community | Small Space Ideas | smallspaceideas | small-space-ideas |\n| Campaign or project | The Weekend Project | theweekendproject | weekend-project |\n| Language or regional audience | Your Brand Español | yourbrand.espanol | brand-spanish |\n\nThese describe what you publish. They are separate from platform settings such as Instagram’s Business or Creator account type, or Google’s Brand Account. A character account can represent a fictional persona; keep that identity clear in its profile.\n\nChoose the accounts that serve your audience. You do not need every type or every platform. For each identity, write down the owner, purpose, desired handle and platforms. Add language or region only when relevant. The examples are naming ideas, not availability checks.\n\nGroup matching profiles across platforms under one Sprid publishing account. For example, your main brand’s Instagram and YouTube can share a destination, while a founder’s account has its own. This keeps content and connections attached to the identity that will publish them.\n\nUse the same owner email and existing business portfolio where appropriate. An Instagram login, a Facebook Page, a Meta business portfolio and a Sprid publishing account are separate objects. Connecting a channel to Sprid does not transfer its ownership to a portfolio.\n\nYour agent can inspect `sprid apps` and reuse existing publishing accounts. Missing destinations can be created with `sprid account create --file account.json`; see the [CLI reference](https://sprid.studio/docs/cli). A Sprid destination does not reserve a handle or create a social account."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "set-up-instagram",
|
|
65
|
+
"title": "Set up Instagram",
|
|
66
|
+
"kind": "steps",
|
|
67
|
+
"markdown": "1. Open [Instagram signup](https://www.instagram.com/accounts/emailsignup/). Reuse an existing account if it already serves the intended purpose.\n2. Enter the owner email, display name and desired handle. Complete the password, birthday and any verification in Instagram itself.\n3. Check the profile’s actual handle and account contact email. Do not assume the requested handle was accepted.\n4. Use a Business or Creator account. Choose Business for a business or brand, or Creator for a creator-led account. Select a category that describes the account.\n5. If you use a Meta business portfolio, have its administrator add the Instagram account there and verify who has control. This is separate from Sprid authorization.\n6. Follow the [Instagram connection guide](https://sprid.studio/docs/connect/instagram), one account at a time.\n\nThe browser connection may offer professional-account conversion directly: **Change → Business → Next → category → Done → Continue**. These labels were observed in September 2026 and may vary. If creating an additional account takes you back to login, finish signup in a separate browser session or the Instagram app; keep the working account signed in."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "set-up-facebook",
|
|
71
|
+
"title": "Set up Facebook",
|
|
72
|
+
"kind": "steps",
|
|
73
|
+
"markdown": "Reuse any existing Page before creating another. For a new Page, open [Create a Page](https://www.facebook.com/pages/create/) under the profile that should manage it. Use the chosen public display name. If a business portfolio should own the Page, have its administrator add or claim it there.\n\nFollow the [Facebook connection guide](https://sprid.studio/docs/connect/facebook). If your profile manages several Pages, choose the specific Page returned by the connection flow. The Facebook profile’s name is not the Page destination."
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": "set-up-youtube",
|
|
77
|
+
"title": "Set up YouTube",
|
|
78
|
+
"kind": "steps",
|
|
79
|
+
"markdown": "Sign in to [YouTube’s channel list](https://www.youtube.com/channel_switcher) with the intended owner’s Google account. Review existing channels, then choose **Create a channel** for each additional identity or audience you want to publish as. Check both the channel name and handle.\n\nIf YouTube asks for advanced-feature verification, the account owner completes the offered verification in YouTube Studio. A submitted video or ID can remain under review. Continue other platforms while approval is pending, then recheck eligibility before retrying channel creation. Do not assume an existing channel’s approval has unlocked every new channel. [YouTube explains eligibility and owner verification](https://support.google.com/youtube/answer/9891124?hl=en).\n\nOnce the channel exists, follow the [YouTube connection guide](https://sprid.studio/docs/connect/youtube) and choose that exact channel in Google’s authorization screen."
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "set-up-tiktok",
|
|
83
|
+
"title": "Set up TikTok",
|
|
84
|
+
"kind": "steps",
|
|
85
|
+
"markdown": "Create or sign in to each intended account in TikTok. Confirm the handle and owner’s recovery access, then follow the [TikTok connection guide](https://sprid.studio/docs/connect/tiktok). Complete any verification yourself. The agent can resume the connection afterward."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "then-run",
|
|
89
|
+
"title": "Then run",
|
|
90
|
+
"kind": "command",
|
|
91
|
+
"markdown": "```sh\nsprid connect instagram --account yourbrand\n```\n\nRepeat with the actual Sprid publishing-account slug and platform: `instagram`, `facebook`, `youtube` or `tiktok`. Connect only accounts that already exist.\n\nIf your agent uses a separate browser session, it can run the command with `--no-browser` and open the returned authorization link in the session signed in to the correct account. Keep that temporary link private. This avoids opening another account’s login in your default browser."
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "how-to-check-it-worked",
|
|
95
|
+
"title": "How to check it worked",
|
|
96
|
+
"kind": "verify",
|
|
97
|
+
"markdown": "Run `sprid status --json` and match the returned platform identity to the intended Sprid publishing account. Record these separately for each platform:\n\n- Account created, with its confirmed handle or Page/channel ID.\n- Owner and business-portfolio access checked.\n- Any provider verification or tester invitation still pending.\n- Sprid connection saved for the correct destination.\n- Publishing tested with explicitly approved content, or still untested.\n\nAn authorization screen saying you allowed access is not proof that Sprid saved a connection. A connected channel is not proof that a post was delivered. Check the platform itself when you authorize a publishing test."
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "if-it-fails",
|
|
101
|
+
"title": "If it fails",
|
|
102
|
+
"kind": "troubleshooting",
|
|
103
|
+
"markdown": "- **Another account appears in authorization:** cancel. Sign in to the intended account and restart the connection. Do not move a working channel just to clear the error.\n- **Several Facebook Pages are listed:** rerun with `--page <id>` using the intended Page’s returned ID.\n- **YouTube verification is pending:** leave its destination pending and continue another platform.\n- **Instagram authorization succeeds but Sprid reports a token-exchange error:** save the error message and contact [Sprid support](mailto:hello@sprid.studio). Sprid must check its Meta permissions and any tester restrictions. You do not need to create your own developer app. A tester invitation, if required, comes from Sprid and must be accepted by the intended Instagram account.\n- **The CLI points to an unavailable local server:** inspect `sprid whoami --json`. For production, use a command-scoped `SPRID_URL=https://api.sprid.studio` and retry. Do not change credentials or another workspace to solve a server-address mismatch."
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "sources",
|
|
107
|
+
"title": "Sources",
|
|
108
|
+
"kind": "sources",
|
|
109
|
+
"markdown": "- [Instagram signup](https://www.instagram.com/accounts/emailsignup/)\n- [Instagram Business Login](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login/)\n- [Meta app modes](https://developers.facebook.com/docs/development/build-and-test/app-modes)\n- [Meta Accounts Center](https://www.facebook.com/help/943858526073065)\n- [Create a Facebook Page](https://www.facebook.com/pages/create/)\n- [YouTube channel list](https://www.youtube.com/channel_switcher)\n- [YouTube feature eligibility](https://support.google.com/youtube/answer/9891124?hl=en)"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"markdown": "# Create your social accounts\n\n**What Sprid does with this:** Connect your brand, creator and other social accounts to their own publishing destinations, so approved content reaches the intended audience.\n\n## You need\n\n- The email address that should own the accounts, access to its inbox, and your phone for verification.\n- Your chosen account names, handles and the purpose of each account. Handles are proposals until the platform confirms them.\n- Access to your existing Meta business portfolio if it should own the Facebook Pages and Instagram accounts.\n\nKeep passwords, verification codes and identity documents in the platform’s own browser or app. An agent can prepare forms and continue after you sign in.\n\n## Set up your account map\n\nYou can connect one main account or several accounts with different purposes. A side account might share educational content, follow a character or cover a topic separately from your main brand.\n\n| Account purpose | Example display name | Example handle | Sprid publishing account |\n|---|---|---|---|\n| Main brand or product | Your Brand | yourbrand | yourbrand |\n| Founder or creator | Alex from Your Brand | alexfromyourbrand | brand-founder |\n| Character or persona | Everyday Alex | everydayalex | everyday-alex |\n| Topic or community | Small Space Ideas | smallspaceideas | small-space-ideas |\n| Campaign or project | The Weekend Project | theweekendproject | weekend-project |\n| Language or regional audience | Your Brand Español | yourbrand.espanol | brand-spanish |\n\nThese describe what you publish. They are separate from platform settings such as Instagram’s Business or Creator account type, or Google’s Brand Account. A character account can represent a fictional persona; keep that identity clear in its profile.\n\nChoose the accounts that serve your audience. You do not need every type or every platform. For each identity, write down the owner, purpose, desired handle and platforms. Add language or region only when relevant. The examples are naming ideas, not availability checks.\n\nGroup matching profiles across platforms under one Sprid publishing account. For example, your main brand’s Instagram and YouTube can share a destination, while a founder’s account has its own. This keeps content and connections attached to the identity that will publish them.\n\nUse the same owner email and existing business portfolio where appropriate. An Instagram login, a Facebook Page, a Meta business portfolio and a Sprid publishing account are separate objects. Connecting a channel to Sprid does not transfer its ownership to a portfolio.\n\nYour agent can inspect `sprid apps` and reuse existing publishing accounts. Missing destinations can be created with `sprid account create --file account.json`; see the [CLI reference](https://sprid.studio/docs/cli). A Sprid destination does not reserve a handle or create a social account.\n\n## Set up Instagram\n\n1. Open [Instagram signup](https://www.instagram.com/accounts/emailsignup/). Reuse an existing account if it already serves the intended purpose.\n2. Enter the owner email, display name and desired handle. Complete the password, birthday and any verification in Instagram itself.\n3. Check the profile’s actual handle and account contact email. Do not assume the requested handle was accepted.\n4. Use a Business or Creator account. Choose Business for a business or brand, or Creator for a creator-led account. Select a category that describes the account.\n5. If you use a Meta business portfolio, have its administrator add the Instagram account there and verify who has control. This is separate from Sprid authorization.\n6. Follow the [Instagram connection guide](https://sprid.studio/docs/connect/instagram), one account at a time.\n\nThe browser connection may offer professional-account conversion directly: **Change → Business → Next → category → Done → Continue**. These labels were observed in September 2026 and may vary. If creating an additional account takes you back to login, finish signup in a separate browser session or the Instagram app; keep the working account signed in.\n\n## Set up Facebook\n\nReuse any existing Page before creating another. For a new Page, open [Create a Page](https://www.facebook.com/pages/create/) under the profile that should manage it. Use the chosen public display name. If a business portfolio should own the Page, have its administrator add or claim it there.\n\nFollow the [Facebook connection guide](https://sprid.studio/docs/connect/facebook). If your profile manages several Pages, choose the specific Page returned by the connection flow. The Facebook profile’s name is not the Page destination.\n\n## Set up YouTube\n\nSign in to [YouTube’s channel list](https://www.youtube.com/channel_switcher) with the intended owner’s Google account. Review existing channels, then choose **Create a channel** for each additional identity or audience you want to publish as. Check both the channel name and handle.\n\nIf YouTube asks for advanced-feature verification, the account owner completes the offered verification in YouTube Studio. A submitted video or ID can remain under review. Continue other platforms while approval is pending, then recheck eligibility before retrying channel creation. Do not assume an existing channel’s approval has unlocked every new channel. [YouTube explains eligibility and owner verification](https://support.google.com/youtube/answer/9891124?hl=en).\n\nOnce the channel exists, follow the [YouTube connection guide](https://sprid.studio/docs/connect/youtube) and choose that exact channel in Google’s authorization screen.\n\n## Set up TikTok\n\nCreate or sign in to each intended account in TikTok. Confirm the handle and owner’s recovery access, then follow the [TikTok connection guide](https://sprid.studio/docs/connect/tiktok). Complete any verification yourself. The agent can resume the connection afterward.\n\n## Then run\n\n```sh\nsprid connect instagram --account yourbrand\n```\n\nRepeat with the actual Sprid publishing-account slug and platform: `instagram`, `facebook`, `youtube` or `tiktok`. Connect only accounts that already exist.\n\nIf your agent uses a separate browser session, it can run the command with `--no-browser` and open the returned authorization link in the session signed in to the correct account. Keep that temporary link private. This avoids opening another account’s login in your default browser.\n\n## How to check it worked\n\nRun `sprid status --json` and match the returned platform identity to the intended Sprid publishing account. Record these separately for each platform:\n\n- Account created, with its confirmed handle or Page/channel ID.\n- Owner and business-portfolio access checked.\n- Any provider verification or tester invitation still pending.\n- Sprid connection saved for the correct destination.\n- Publishing tested with explicitly approved content, or still untested.\n\nAn authorization screen saying you allowed access is not proof that Sprid saved a connection. A connected channel is not proof that a post was delivered. Check the platform itself when you authorize a publishing test.\n\n## If it fails\n\n- **Another account appears in authorization:** cancel. Sign in to the intended account and restart the connection. Do not move a working channel just to clear the error.\n- **Several Facebook Pages are listed:** rerun with `--page <id>` using the intended Page’s returned ID.\n- **YouTube verification is pending:** leave its destination pending and continue another platform.\n- **Instagram authorization succeeds but Sprid reports a token-exchange error:** save the error message and contact [Sprid support](mailto:hello@sprid.studio). Sprid must check its Meta permissions and any tester restrictions. You do not need to create your own developer app. A tester invitation, if required, comes from Sprid and must be accepted by the intended Instagram account.\n- **The CLI points to an unavailable local server:** inspect `sprid whoami --json`. For production, use a command-scoped `SPRID_URL=https://api.sprid.studio` and retry. Do not change credentials or another workspace to solve a server-address mismatch.\n\n## Sources\n\n- [Instagram signup](https://www.instagram.com/accounts/emailsignup/)\n- [Instagram Business Login](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login/)\n- [Meta app modes](https://developers.facebook.com/docs/development/build-and-test/app-modes)\n- [Meta Accounts Center](https://www.facebook.com/help/943858526073065)\n- [Create a Facebook Page](https://www.facebook.com/pages/create/)\n- [YouTube channel list](https://www.youtube.com/channel_switcher)\n- [YouTube feature eligibility](https://support.google.com/youtube/answer/9891124?hl=en)\n",
|
|
113
|
+
"revision": "037b74ff55bb32a8"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "app-store-connect",
|
|
117
|
+
"title": "App Store Connect",
|
|
118
|
+
"summary": "Read App Store reviews and download reports, and update listing copy when you approve it.",
|
|
119
|
+
"command": "sprid connect asc --key ~/Downloads/AuthKey_XXXXXXXXXX.p8 --key-id XXXXXXXXXX --issuer YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY",
|
|
120
|
+
"url": "https://sprid.studio/docs/connect/app-store-connect",
|
|
121
|
+
"sections": [
|
|
122
|
+
{
|
|
123
|
+
"id": "you-need",
|
|
124
|
+
"title": "You need",
|
|
125
|
+
"kind": "requirements",
|
|
126
|
+
"markdown": "**Account Holder** or **Admin** access to your Apple Developer team. You will create a **Team API key** with **Admin** access; it covers every app on the account.\n\nIf you only want to read reviews and edit metadata, **App Manager** access is sufficient. Use Admin for review replies and analytics reports."
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "click-path-appstoreconnectapplecom-checked-2026-09-08",
|
|
130
|
+
"title": "Click path (appstoreconnect.apple.com, checked 2026-09-08)",
|
|
131
|
+
"kind": "steps",
|
|
132
|
+
"markdown": "1. Open [App Store Connect](https://appstoreconnect.apple.com) → **Users and Access → Integrations → App Store Connect API → Team Keys**.\n2. Click **Generate API Key**, or **+** beside **Active**.\n3. Name the key `Sprid`, choose **Admin** access, then click **Generate**.\n4. Click **Download API Key** and keep the `.p8` file. Apple offers this download once; if lost, revoke the key and create another.\n5. Copy the **Key ID** from its row and the **Issuer ID** above the table. Use these in the command below."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "find-the-apps-numeric-id",
|
|
136
|
+
"title": "Find the app's numeric id",
|
|
137
|
+
"kind": "identifiers",
|
|
138
|
+
"markdown": "Open **Apps → your app → General → App Information → General Information → Apple ID**. If your Sprid app profile is missing this number, run `sprid init` to add it."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "then-run",
|
|
142
|
+
"title": "Then run",
|
|
143
|
+
"kind": "command",
|
|
144
|
+
"markdown": "```\nsprid connect asc --key ~/Downloads/AuthKey_XXXXXXXXXX.p8 --key-id XXXXXXXXXX --issuer YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY\n```\n\nReplace the file path and ids with yours. Keep the key file private; do not paste its contents into chat."
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"id": "how-to-check-it-worked",
|
|
148
|
+
"title": "How to check it worked",
|
|
149
|
+
"kind": "verify",
|
|
150
|
+
"markdown": "Run `sprid status` to check setup. Then ask your agent: “Check that Sprid can read this app’s App Store reviews and analytics. Tell me if any reports are still missing.”\n\nA saved key alone does not confirm access. The daily review email only arrives when there are new reviews."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "if-it-fails",
|
|
154
|
+
"title": "If it fails",
|
|
155
|
+
"kind": "troubleshooting",
|
|
156
|
+
"markdown": "- **Key not accepted:** check the Key ID matches the downloaded file and the Issuer ID came from above the keys table. A Team ID will not work here.\n- **Permission denied:** create a replacement key with **Admin** access. An existing key’s role cannot be changed.\n- **Older analytics are missing:** Apple starts preparing reports after setup. Missing history does not mean downloads fell to zero."
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"id": "sources",
|
|
160
|
+
"title": "Sources",
|
|
161
|
+
"kind": "sources",
|
|
162
|
+
"markdown": "- [Generate keys](https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api)\n- [Role permissions](https://developer.apple.com/help/app-store-connect/reference/account-management/role-permissions)\n- [Respond to reviews](https://developer.apple.com/help/app-store-connect/monitor-ratings-and-reviews/respond-to-reviews)\n- [API key access levels compared](https://aso.dev/app-store-connect/api-key-access-levels/)\n- [App Manager 403 on review replies](https://developer.apple.com/forums/thread/800545)"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"id": "investigate-with-this-connection",
|
|
166
|
+
"title": "Investigate with this connection",
|
|
167
|
+
"kind": "detail",
|
|
168
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `reviews`, `versions`, `reports`, `report_rows`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source asc --json\n```\n\nPinned app. Reviews and existing analytics report definitions are read-only. No report request is created. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
"markdown": "# App Store Connect\n\n**What Sprid does with this:** Read App Store reviews and download reports, and update listing copy when you approve it.\n\n## You need\n\n**Account Holder** or **Admin** access to your Apple Developer team. You will create a **Team API key** with **Admin** access; it covers every app on the account.\n\nIf you only want to read reviews and edit metadata, **App Manager** access is sufficient. Use Admin for review replies and analytics reports.\n\n## Click path (appstoreconnect.apple.com, checked 2026-09-08)\n\n1. Open [App Store Connect](https://appstoreconnect.apple.com) → **Users and Access → Integrations → App Store Connect API → Team Keys**.\n2. Click **Generate API Key**, or **+** beside **Active**.\n3. Name the key `Sprid`, choose **Admin** access, then click **Generate**.\n4. Click **Download API Key** and keep the `.p8` file. Apple offers this download once; if lost, revoke the key and create another.\n5. Copy the **Key ID** from its row and the **Issuer ID** above the table. Use these in the command below.\n\n## Find the app's numeric id\n\nOpen **Apps → your app → General → App Information → General Information → Apple ID**. If your Sprid app profile is missing this number, run `sprid init` to add it.\n\n## Then run\n\n```\nsprid connect asc --key ~/Downloads/AuthKey_XXXXXXXXXX.p8 --key-id XXXXXXXXXX --issuer YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY\n```\n\nReplace the file path and ids with yours. Keep the key file private; do not paste its contents into chat.\n\n## How to check it worked\n\nRun `sprid status` to check setup. Then ask your agent: “Check that Sprid can read this app’s App Store reviews and analytics. Tell me if any reports are still missing.”\n\nA saved key alone does not confirm access. The daily review email only arrives when there are new reviews.\n\n## If it fails\n\n- **Key not accepted:** check the Key ID matches the downloaded file and the Issuer ID came from above the keys table. A Team ID will not work here.\n- **Permission denied:** create a replacement key with **Admin** access. An existing key’s role cannot be changed.\n- **Older analytics are missing:** Apple starts preparing reports after setup. Missing history does not mean downloads fell to zero.\n\n## Sources\n\n- [Generate keys](https://developer.apple.com/help/app-store-connect/get-started/app-store-connect-api)\n- [Role permissions](https://developer.apple.com/help/app-store-connect/reference/account-management/role-permissions)\n- [Respond to reviews](https://developer.apple.com/help/app-store-connect/monitor-ratings-and-reviews/respond-to-reviews)\n- [API key access levels compared](https://aso.dev/app-store-connect/api-key-access-levels/)\n- [App Manager 403 on review replies](https://developer.apple.com/forums/thread/800545)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `reviews`, `versions`, `reports`, `report_rows`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source asc --json\n```\n\nPinned app. Reviews and existing analytics report definitions are read-only. No report request is created. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
172
|
+
"revision": "788c2f1980b1bd27"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"id": "google-play",
|
|
176
|
+
"title": "Google Play",
|
|
177
|
+
"summary": "Read Google Play reviews and download reports, and update listing copy when you approve it.",
|
|
178
|
+
"command": "sprid connect play --key ~/Downloads/play-sa.json",
|
|
179
|
+
"url": "https://sprid.studio/docs/connect/google-play",
|
|
180
|
+
"sections": [
|
|
181
|
+
{
|
|
182
|
+
"id": "you-need",
|
|
183
|
+
"title": "You need",
|
|
184
|
+
"kind": "requirements",
|
|
185
|
+
"markdown": "**Owner** or **Admin** access in Play Console, plus a Google Cloud project where you can create a service account. The project does not need to be linked to Play Console."
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": "click-path",
|
|
189
|
+
"title": "Click path",
|
|
190
|
+
"kind": "steps",
|
|
191
|
+
"markdown": "### A. Google Cloud\n\n1. Open [Google Cloud](https://console.cloud.google.com) and select or create a project.\n2. Open **APIs & Services → Library**. Find **Google Play Android Developer API** and click **Enable**.\n3. For statistics reports, also enable **Google Play Developer Reporting API**.\n4. Open **IAM & Admin → Service Accounts → Create service account**. Name it `sprid-play`, click **Create and continue**, then **Done**. Leave Cloud roles empty.\n5. Open the account → **Keys → Add key → Create new key → JSON → Create**. Save the download as `play-sa.json`; keep it private.\n6. Copy the service account’s email address.\n\n### B. Play Console\n\n7. Open [Play Console](https://play.google.com/console) → **Users and permissions → Invite new users**. Enter the service account’s email and leave access expiry unset.\n8. Under **App permissions → Add app**, select your app and click **Apply**.\n9. Enable **View app information (read-only)** and **Reply to reviews**. Add **Manage store presence** if you want to update listing copy. Leave financial access off.\n10. Click **Invite user → Send invite**."
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "find-the-package-name",
|
|
195
|
+
"title": "Find the package name",
|
|
196
|
+
"kind": "identifiers",
|
|
197
|
+
"markdown": "Copy the package name beneath your app’s name on its Play Console **Dashboard**, such as `com.example.app`. Run `sprid init` if your Sprid app profile is missing it.\n\nFor download reports, copy the **Cloud Storage URI** from **Download reports → Statistics** into `playExportBucket` in `.sprid/app.json`. These reports also need the account-level **View app information and download bulk reports (read-only)** permission."
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"id": "then-run",
|
|
201
|
+
"title": "Then run",
|
|
202
|
+
"kind": "command",
|
|
203
|
+
"markdown": "```\nsprid connect play --key ~/Downloads/play-sa.json\n```\n\nUse the path to your downloaded file. Do not paste its contents into chat."
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"id": "how-to-check-it-worked",
|
|
207
|
+
"title": "How to check it worked",
|
|
208
|
+
"kind": "verify",
|
|
209
|
+
"markdown": "Run `sprid status`, then ask your agent: “Check that Sprid can read this app’s Play reviews and download reports. Tell me what is missing.”\n\nThe review email only arrives when new reviews are available. Only recent reviews with written text can be imported initially."
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"id": "if-it-fails",
|
|
213
|
+
"title": "If it fails",
|
|
214
|
+
"kind": "troubleshooting",
|
|
215
|
+
"markdown": "- **Permission denied:** check the service account appears under **Users and permissions** with your app selected. New permissions may take time to apply; integrators report up to 24 hours, which Google’s docs do not confirm.\n- **Google Play’s API is switched off:** enable **Google Play Android Developer API** in the Cloud project used to create the service account. Use the project link in Sprid’s error message.\n- **Reviews are empty:** older reviews and star-only ratings may be visible in the store but unavailable to Sprid."
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"id": "sources",
|
|
219
|
+
"title": "Sources",
|
|
220
|
+
"kind": "sources",
|
|
221
|
+
"markdown": "- [Getting started](https://developers.google.com/android-publisher/getting_started)\n- [Permission names in Users and permissions](https://support.google.com/googleplay/android-developer/answer/9844686)\n- [Reviews API only returns recent reviews](https://developers.google.com/android-publisher/reply-to-reviews)\n- [24-hour propagation](https://docs.apphud.com/docs/google-play-service-credentials)\n- [24-hour propagation](https://documentation.qonversion.io/docs/service-account-key-android)"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"id": "investigate-with-this-connection",
|
|
225
|
+
"title": "Investigate with this connection",
|
|
226
|
+
"kind": "detail",
|
|
227
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `reviews`, `report_rows`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source play --json\n```\n\nPinned package. Live reviews have provider history limits; exported acquisition rows require the saved Play export bucket. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
"markdown": "# Google Play\n\n**What Sprid does with this:** Read Google Play reviews and download reports, and update listing copy when you approve it.\n\n## You need\n\n**Owner** or **Admin** access in Play Console, plus a Google Cloud project where you can create a service account. The project does not need to be linked to Play Console.\n\n## Click path\n\n### A. Google Cloud\n\n1. Open [Google Cloud](https://console.cloud.google.com) and select or create a project.\n2. Open **APIs & Services → Library**. Find **Google Play Android Developer API** and click **Enable**.\n3. For statistics reports, also enable **Google Play Developer Reporting API**.\n4. Open **IAM & Admin → Service Accounts → Create service account**. Name it `sprid-play`, click **Create and continue**, then **Done**. Leave Cloud roles empty.\n5. Open the account → **Keys → Add key → Create new key → JSON → Create**. Save the download as `play-sa.json`; keep it private.\n6. Copy the service account’s email address.\n\n### B. Play Console\n\n7. Open [Play Console](https://play.google.com/console) → **Users and permissions → Invite new users**. Enter the service account’s email and leave access expiry unset.\n8. Under **App permissions → Add app**, select your app and click **Apply**.\n9. Enable **View app information (read-only)** and **Reply to reviews**. Add **Manage store presence** if you want to update listing copy. Leave financial access off.\n10. Click **Invite user → Send invite**.\n\n## Find the package name\n\nCopy the package name beneath your app’s name on its Play Console **Dashboard**, such as `com.example.app`. Run `sprid init` if your Sprid app profile is missing it.\n\nFor download reports, copy the **Cloud Storage URI** from **Download reports → Statistics** into `playExportBucket` in `.sprid/app.json`. These reports also need the account-level **View app information and download bulk reports (read-only)** permission.\n\n## Then run\n\n```\nsprid connect play --key ~/Downloads/play-sa.json\n```\n\nUse the path to your downloaded file. Do not paste its contents into chat.\n\n## How to check it worked\n\nRun `sprid status`, then ask your agent: “Check that Sprid can read this app’s Play reviews and download reports. Tell me what is missing.”\n\nThe review email only arrives when new reviews are available. Only recent reviews with written text can be imported initially.\n\n## If it fails\n\n- **Permission denied:** check the service account appears under **Users and permissions** with your app selected. New permissions may take time to apply; integrators report up to 24 hours, which Google’s docs do not confirm.\n- **Google Play’s API is switched off:** enable **Google Play Android Developer API** in the Cloud project used to create the service account. Use the project link in Sprid’s error message.\n- **Reviews are empty:** older reviews and star-only ratings may be visible in the store but unavailable to Sprid.\n\n## Sources\n\n- [Getting started](https://developers.google.com/android-publisher/getting_started)\n- [Permission names in Users and permissions](https://support.google.com/googleplay/android-developer/answer/9844686)\n- [Reviews API only returns recent reviews](https://developers.google.com/android-publisher/reply-to-reviews)\n- [24-hour propagation](https://docs.apphud.com/docs/google-play-service-credentials)\n- [24-hour propagation](https://documentation.qonversion.io/docs/service-account-key-android)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `reviews`, `report_rows`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source play --json\n```\n\nPinned package. Live reviews have provider history limits; exported acquisition rows require the saved Play export bucket. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
231
|
+
"revision": "7794554f047a38dd"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"id": "search-console",
|
|
235
|
+
"title": "Google Search Console",
|
|
236
|
+
"summary": "See which Google searches bring people to your website.",
|
|
237
|
+
"command": "sprid connect gsc --key ~/Downloads/gsc-sa.json --property sc-domain:example.com",
|
|
238
|
+
"url": "https://sprid.studio/docs/connect/search-console",
|
|
239
|
+
"sections": [
|
|
240
|
+
{
|
|
241
|
+
"id": "you-need",
|
|
242
|
+
"title": "You need",
|
|
243
|
+
"kind": "requirements",
|
|
244
|
+
"markdown": "**Owner** access to your website’s Search Console property. You can reuse the Google service account created for Sprid’s Play connection."
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"id": "click-path",
|
|
248
|
+
"title": "Click path",
|
|
249
|
+
"kind": "steps",
|
|
250
|
+
"markdown": "### A. Google Cloud\n\n1. Open [Google Cloud](https://console.cloud.google.com) and select the project for your service account.\n2. Under **APIs & Services → Library**, find **Google Search Console API** and click **Enable**.\n3. If you need a service account, open **IAM & Admin → Service Accounts → Create service account**, name it `sprid-gsc`, then click **Done**.\n4. Open the account → **Keys → Add key → Create new key → JSON**. Save the file as `gsc-sa.json` and copy the account’s email. If reusing an account, use its existing key file and email.\n\n### B. Search Console\n\n5. Open [Search Console](https://search.google.com/search-console) and select your website in the top-left dropdown.\n6. Open **Settings → Users and permissions → Add user**.\n7. Enter the service account’s email, choose **Restricted**, then click **Add**."
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"id": "domain-property-vs-url-prefix-and-the-property-string",
|
|
254
|
+
"title": "Domain property vs URL prefix, and the property string",
|
|
255
|
+
"kind": "identifiers",
|
|
256
|
+
"markdown": "Use the property you just granted access to:\n\n| Property shown in Search Console | Value to use below |\n|---|---|\n| Domain, such as `example.com` | `sc-domain:example.com` |\n| URL prefix, such as `https://www.example.com/` | The exact URL, including its final slash |\n\nA domain property covers all versions of your domain. Check **Settings → Property settings** if unsure which kind you have."
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"id": "then-run",
|
|
260
|
+
"title": "Then run",
|
|
261
|
+
"kind": "command",
|
|
262
|
+
"markdown": "```\nsprid connect gsc --key ~/Downloads/gsc-sa.json --property sc-domain:example.com\n```\n\nReplace the file path and property with yours. Keep the downloaded file private."
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"id": "how-to-check-it-worked",
|
|
266
|
+
"title": "How to check it worked",
|
|
267
|
+
"kind": "verify",
|
|
268
|
+
"markdown": "Run `sprid status`, then ask your agent: “Read recent Google search results for this website through Sprid and check that the property is correct.”\n\nA saved key confirms setup; the live read confirms access. The newest dates may be missing because Google’s reports arrive late."
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"id": "if-it-fails",
|
|
272
|
+
"title": "If it fails",
|
|
273
|
+
"kind": "troubleshooting",
|
|
274
|
+
"markdown": "- **Access denied:** check the service account’s email was added to the exact property in your command. If both match, try **Full** permission. Do not grant Owner.\n- **Property not found:** check the domain or URL, including `www`, `https` and the final slash.\n- **Recent dates are empty:** try an earlier period; the latest few days may still be processing."
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"id": "sources",
|
|
278
|
+
"title": "Sources",
|
|
279
|
+
"kind": "sources",
|
|
280
|
+
"markdown": "- [Permission levels and Add user path](https://support.google.com/webmasters/answer/7687615)\n- [`siteUrl` formats](https://developers.google.com/webmaster-tools/v1/searchanalytics/query)\n- [Service account rights vs Owner](https://www.indexernow.com/fix/service-account-owner-gsc)"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"id": "investigate-with-this-connection",
|
|
284
|
+
"title": "Investigate with this connection",
|
|
285
|
+
"kind": "detail",
|
|
286
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `search`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source gsc --json\n```\n\nPinned Search Console property. Dates use Pacific time; anonymized queries and top-row limits affect coverage. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
"markdown": "# Google Search Console\n\n**What Sprid does with this:** See which Google searches bring people to your website.\n\n## You need\n\n**Owner** access to your website’s Search Console property. You can reuse the Google service account created for Sprid’s Play connection.\n\n## Click path\n\n### A. Google Cloud\n\n1. Open [Google Cloud](https://console.cloud.google.com) and select the project for your service account.\n2. Under **APIs & Services → Library**, find **Google Search Console API** and click **Enable**.\n3. If you need a service account, open **IAM & Admin → Service Accounts → Create service account**, name it `sprid-gsc`, then click **Done**.\n4. Open the account → **Keys → Add key → Create new key → JSON**. Save the file as `gsc-sa.json` and copy the account’s email. If reusing an account, use its existing key file and email.\n\n### B. Search Console\n\n5. Open [Search Console](https://search.google.com/search-console) and select your website in the top-left dropdown.\n6. Open **Settings → Users and permissions → Add user**.\n7. Enter the service account’s email, choose **Restricted**, then click **Add**.\n\n## Domain property vs URL prefix, and the property string\n\nUse the property you just granted access to:\n\n| Property shown in Search Console | Value to use below |\n|---|---|\n| Domain, such as `example.com` | `sc-domain:example.com` |\n| URL prefix, such as `https://www.example.com/` | The exact URL, including its final slash |\n\nA domain property covers all versions of your domain. Check **Settings → Property settings** if unsure which kind you have.\n\n## Then run\n\n```\nsprid connect gsc --key ~/Downloads/gsc-sa.json --property sc-domain:example.com\n```\n\nReplace the file path and property with yours. Keep the downloaded file private.\n\n## How to check it worked\n\nRun `sprid status`, then ask your agent: “Read recent Google search results for this website through Sprid and check that the property is correct.”\n\nA saved key confirms setup; the live read confirms access. The newest dates may be missing because Google’s reports arrive late.\n\n## If it fails\n\n- **Access denied:** check the service account’s email was added to the exact property in your command. If both match, try **Full** permission. Do not grant Owner.\n- **Property not found:** check the domain or URL, including `www`, `https` and the final slash.\n- **Recent dates are empty:** try an earlier period; the latest few days may still be processing.\n\n## Sources\n\n- [Permission levels and Add user path](https://support.google.com/webmasters/answer/7687615)\n- [`siteUrl` formats](https://developers.google.com/webmaster-tools/v1/searchanalytics/query)\n- [Service account rights vs Owner](https://www.indexernow.com/fix/service-account-owner-gsc)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `search`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source gsc --json\n```\n\nPinned Search Console property. Dates use Pacific time; anonymized queries and top-row limits affect coverage. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
290
|
+
"revision": "25575eceae015c1f"
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"id": "posthog",
|
|
294
|
+
"title": "PostHog",
|
|
295
|
+
"summary": "See how people use your app and where they stop.",
|
|
296
|
+
"command": "sprid connect posthog --app myapp --key ~/keys/posthog-myapp.txt --project 12345 --host eu",
|
|
297
|
+
"url": "https://sprid.studio/docs/connect/posthog",
|
|
298
|
+
"sections": [
|
|
299
|
+
{
|
|
300
|
+
"id": "you-need",
|
|
301
|
+
"title": "You need",
|
|
302
|
+
"kind": "requirements",
|
|
303
|
+
"markdown": "Access to your app’s PostHog project and permission to create a **personal API key**. Your app must already send events to PostHog; connecting Sprid does not add tracking."
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"id": "click-path-usposthogcom-or-euposthogcom",
|
|
307
|
+
"title": "Click path (us.posthog.com or eu.posthog.com)",
|
|
308
|
+
"kind": "steps",
|
|
309
|
+
"markdown": "1. In PostHog, open **Settings → Account → Personal API keys**.\n2. Click **Create personal API key** and name it `Sprid <app name>`.\n3. Under access, select **Projects** and choose your app’s project. Leave **All access** off.\n4. Select **Query → Read** and **Project → Read**. Leave write access off.\n5. Create the key, copy it before closing the dialog and save it to a private file such as `~/keys/posthog-myapp.txt`.\n\nCreate a separate key for each app. The public key used inside your app cannot be used for this connection."
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"id": "project-id-and-host",
|
|
313
|
+
"title": "Project id and host",
|
|
314
|
+
"kind": "identifiers",
|
|
315
|
+
"markdown": "- **Project id:** the number after `/project/` in your PostHog address, such as `12345`.\n- **Host:** `eu` for `eu.posthog.com`, `us` for `us.posthog.com`, or your full self-hosted address. Use the address where you open the dashboard."
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"id": "then-run",
|
|
319
|
+
"title": "Then run",
|
|
320
|
+
"kind": "command",
|
|
321
|
+
"markdown": "```sh\nsprid connect posthog --app myapp --key ~/keys/posthog-myapp.txt --project 12345 --host eu\n```\n\nReplace `myapp` with your Sprid app slug and use your own file path, project id and host. Add `--workspace <slug>` if needed. Do not paste the key into chat."
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"id": "how-to-check-it-worked",
|
|
325
|
+
"title": "How to check it worked",
|
|
326
|
+
"kind": "verify",
|
|
327
|
+
"markdown": "Ask your agent: “Check that Sprid can read recent PostHog events for this app, and confirm the project is correct.”\n\nA saved connection alone does not prove events are arriving. The check should report recent activity or explain why it is missing."
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"id": "metric-definitions",
|
|
331
|
+
"title": "Metric definitions",
|
|
332
|
+
"kind": "detail",
|
|
333
|
+
"markdown": "Open **Settings → Apps → your app → PostHog**. Set the account-created event\nand the first UTC date from which tracking is complete. Defaults:\n\n| Metric | What counts |\n|---|---|\n| Registrations | First `sprid_signup` event per PostHog person, across all surfaces |\n| New app users | First native app activity, including anonymous people |\n| Active app users | Distinct people with native activity during the period |\n| Web visitors | Distinct website pageview visitors on the saved hostname |\n\nSend `sprid_signup` from your server **after account creation**, with the account\nid as `distinct_id`. Identify that same id in your clients. Never fire it on\nlogin, page load or install. Existing `posthogEvents.signup` mappings work too;\n`posthogConfig.registration.event` takes precedence. No matching event history\nmeans unavailable; recorded history with no new registrations means zero.\nPeriods before the tracking start are unavailable. Comparisons crossing it are\nwithheld, as are comparisons without a confirmed start. Backfill using original creation timestamps.\n\nNative defaults require `posthog-react-native` plus iOS/iPadOS/Android and reject\nexplicit web surfaces. Set `app_surface: 'web'` on Expo web and `'native'` on devices.\nWeb counts require a browser and exclude reported bots and crawler user agents.\nEvery metric excludes event/person `is_internal`, `is_test` and `sprid_test = true`.\nThese are observed identities, not a guarantee that every remaining visitor is human.\n\n### Custom properties\n\nExpand **Custom properties** for advanced rules. Example JSON:\n\n```json\n{\"registration\":{\"identity\":{\"scope\":\"event\",\"property\":\"account_id\"}},\"app\":{\"filters\":[{\"scope\":\"event\",\"property\":\"client_type\",\"operator\":\"in\",\"values\":[\"native\"]}]},\"exclude\":[{\"scope\":\"person\",\"property\":\"staff\",\"operator\":\"in\",\"values\":[true]}]}\n```\n\n`app.filters` replaces SDK/OS matching with your positive native rule. All app\nfilters must match. Each `exclude` rule removes matching traffic from all metrics.\n`registration.filters` narrows the selected event (for example `result = success`).\nUse `scope: event|person`, `operator: in|not_in` and string, number or boolean\n`values`. Missing properties fail `in` and pass `not_in`. Property names are literal\nkeys, including dots. Registration identity defaults to `person_id`; a configured\nidentity property must be present. It counts accounts, so it should be immutable.\n\nThe same object is `posthogConfig` in REST `PATCH /api/app-profiles/:id`, MCP\n`upsert_app_profile`, and the App Profile JSON used by `sprid init`. Add\n`registration.event` and `registration.since` there; the form edits those separately.\nNo credentials or SQL belong in this object. Fetch Insights after saving and check\nits registration notes and totals against your database before trusting a funnel."
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"id": "review-suspected-automated-traffic",
|
|
337
|
+
"title": "Review suspected automated traffic",
|
|
338
|
+
"kind": "detail",
|
|
339
|
+
"markdown": "Open **Web visitors → Review traffic exclusions**, or **Settings → Apps → your\napp → PostHog → Review traffic**. Inspect a UTC date range, choose a traffic\ngroup and preview its effect before saving. A spike or a shared device\nfingerprint alone does not prove that visitors are bots. **How to tell a\nscraper from an audience, and the traps in doing it, are in\n[Check whether a traffic spike is real](https://sprid.studio/docs/traffic)**\n(`sprid docs traffic`). Read that before saving a rule.\n\nSaved exclusions apply by default to Sprid’s website totals, charts, breakdowns,\nsocial attribution and weekly website counts, including the comparison period.\nThey are app-specific and date-bounded. All properties inside a rule must match;\nmatching any enabled rule excludes the event. Remaining visitors are counted\nagain as distinct people, never by subtracting overlapping group totals.\nNative app activity and registrations are unchanged. **Restore this traffic**\ndisables a rule. Original PostHog data is never changed or deleted. Raw connected\nqueries and the marketing-review event inventory remain unfiltered evidence;\nuse Insights for the corrected website figures.\n\nAgents use MCP `review_traffic`, or REST\n`POST /api/app-profiles/:ref/traffic-review?workspaceId=…` with\n`{\"start\":\"2026-09-18\",\"end\":\"2026-09-19\"}`. End dates are exclusive, UTC;\nreview ranges are at most 31 days. An optional `exclusion` previews a rule\nagainst this period and the one before it. Save approved rules through\n`upsert_app_profile` or the profile PATCH route in\n`posthogConfig.trafficExclusions`, preserving the other configuration. Sprid\nrecords the last editor and update time. The vocabulary is provider-neutral;\ncurrently only PostHog is supported."
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"id": "social-traffic-and-clip-comparisons",
|
|
343
|
+
"title": "Social traffic and clip comparisons",
|
|
344
|
+
"kind": "detail",
|
|
345
|
+
"markdown": "Save the app’s website URL on its App Profile as well as the PostHog connection.\nInsights compares completed-day website sessions with recorded social view gains.\nShared bio traffic stays at channel level; only a dedicated tagged link identifies\nan individual publish. Older clips with metric activity remain candidates.\n\nCopy stable bio links and dedicated clip links from Insights. Preserve\n`utm_source`, `utm_medium`, `sprid_account` and, for dedicated links only,\n`sprid_publish` through redirects. Never rotate the shared bio link to the newest\npublish. The optional bio-page HTML export records selections separately and\nkeeps a direct app link. Host it on the saved website hostname, with your existing\nPostHog initialization.\n\nTo capture store-link clicks and explicit website outcomes, include after the\nsite’s existing PostHog initialization:\n\n```html\n<script src=\"https://sprid.studio/sprid-attribution.js\" defer></script>\n```\n\nThis adapter uses your client and consent state; it sends nothing to Sprid.\nCall `window.spridAttribution?.track('signup')` or `.track('activation')` only\nafter that action succeeds. Existing App Profile `posthogEvents.signup` and\n`posthogEvents.activation` mappings are also accepted when the events share the\narriving website session. The adapter does not add tracking to a native app or\njoin website visits to purchases. A store click is not an install.\n\nMissing outcomes stay unmeasured. Redirect-only flows need a pre-navigation\nbeacon; redirect events are counted separately from website sessions.\n`get_insights` and `sprid insights` return the same evidence as the dashboard."
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"id": "if-it-fails",
|
|
349
|
+
"title": "If it fails",
|
|
350
|
+
"kind": "troubleshooting",
|
|
351
|
+
"markdown": "- **Access denied:** check the key is active, grants your project and has both Read permissions above. Reconnect with the corrected key file.\n- **Project not found:** check the project number and host together. A US project needs the US host.\n- **Connected but no events:** check the dates and project first. Then ask your agent to check whether your app’s tracking is sending events."
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"id": "sources-and-verification",
|
|
355
|
+
"title": "Sources and verification",
|
|
356
|
+
"kind": "sources",
|
|
357
|
+
"markdown": "Setup and live data reads checked on 2026-09-09.\n\n- [PostHog personal API keys](https://posthog.com/docs/api/personal-api-keys)\n- [Project identity endpoint](https://posthog.com/docs/api/projects)\n- [HogQL query endpoint](https://posthog.com/docs/api/query)\n- [SDK and framework guides](https://posthog.com/docs/libraries)\n- [React Native screen tracking](https://posthog.com/docs/libraries/react-native)\n- [Identifying users](https://posthog.com/docs/product-analytics/identify)\n- [Funnels](https://posthog.com/docs/product-analytics/funnels)"
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"id": "investigate-with-this-connection",
|
|
361
|
+
"title": "Investigate with this connection",
|
|
362
|
+
"kind": "detail",
|
|
363
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `query`, `events`, `properties`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source posthog --json\n```\n\nProject-pinned analytics. SQL is HogQL; inspect instrumentation before interpreting events. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n\nEvent-definition discovery additionally needs `event_definition:read`; property-definition discovery needs `property_definition:read`. Keep `query:read` and `project:read` for SQL and project verification. Restrict all of them to the saved project."
|
|
364
|
+
}
|
|
365
|
+
],
|
|
366
|
+
"markdown": "# PostHog\n\n**What Sprid does with this:** See how people use your app and where they stop.\n\n## You need\n\nAccess to your app’s PostHog project and permission to create a **personal API key**. Your app must already send events to PostHog; connecting Sprid does not add tracking.\n\n## Click path (us.posthog.com or eu.posthog.com)\n\n1. In PostHog, open **Settings → Account → Personal API keys**.\n2. Click **Create personal API key** and name it `Sprid <app name>`.\n3. Under access, select **Projects** and choose your app’s project. Leave **All access** off.\n4. Select **Query → Read** and **Project → Read**. Leave write access off.\n5. Create the key, copy it before closing the dialog and save it to a private file such as `~/keys/posthog-myapp.txt`.\n\nCreate a separate key for each app. The public key used inside your app cannot be used for this connection.\n\n## Project id and host\n\n- **Project id:** the number after `/project/` in your PostHog address, such as `12345`.\n- **Host:** `eu` for `eu.posthog.com`, `us` for `us.posthog.com`, or your full self-hosted address. Use the address where you open the dashboard.\n\n## Then run\n\n```sh\nsprid connect posthog --app myapp --key ~/keys/posthog-myapp.txt --project 12345 --host eu\n```\n\nReplace `myapp` with your Sprid app slug and use your own file path, project id and host. Add `--workspace <slug>` if needed. Do not paste the key into chat.\n\n## How to check it worked\n\nAsk your agent: “Check that Sprid can read recent PostHog events for this app, and confirm the project is correct.”\n\nA saved connection alone does not prove events are arriving. The check should report recent activity or explain why it is missing.\n\n## Metric definitions\n\nOpen **Settings → Apps → your app → PostHog**. Set the account-created event\nand the first UTC date from which tracking is complete. Defaults:\n\n| Metric | What counts |\n|---|---|\n| Registrations | First `sprid_signup` event per PostHog person, across all surfaces |\n| New app users | First native app activity, including anonymous people |\n| Active app users | Distinct people with native activity during the period |\n| Web visitors | Distinct website pageview visitors on the saved hostname |\n\nSend `sprid_signup` from your server **after account creation**, with the account\nid as `distinct_id`. Identify that same id in your clients. Never fire it on\nlogin, page load or install. Existing `posthogEvents.signup` mappings work too;\n`posthogConfig.registration.event` takes precedence. No matching event history\nmeans unavailable; recorded history with no new registrations means zero.\nPeriods before the tracking start are unavailable. Comparisons crossing it are\nwithheld, as are comparisons without a confirmed start. Backfill using original creation timestamps.\n\nNative defaults require `posthog-react-native` plus iOS/iPadOS/Android and reject\nexplicit web surfaces. Set `app_surface: 'web'` on Expo web and `'native'` on devices.\nWeb counts require a browser and exclude reported bots and crawler user agents.\nEvery metric excludes event/person `is_internal`, `is_test` and `sprid_test = true`.\nThese are observed identities, not a guarantee that every remaining visitor is human.\n\n### Custom properties\n\nExpand **Custom properties** for advanced rules. Example JSON:\n\n```json\n{\"registration\":{\"identity\":{\"scope\":\"event\",\"property\":\"account_id\"}},\"app\":{\"filters\":[{\"scope\":\"event\",\"property\":\"client_type\",\"operator\":\"in\",\"values\":[\"native\"]}]},\"exclude\":[{\"scope\":\"person\",\"property\":\"staff\",\"operator\":\"in\",\"values\":[true]}]}\n```\n\n`app.filters` replaces SDK/OS matching with your positive native rule. All app\nfilters must match. Each `exclude` rule removes matching traffic from all metrics.\n`registration.filters` narrows the selected event (for example `result = success`).\nUse `scope: event|person`, `operator: in|not_in` and string, number or boolean\n`values`. Missing properties fail `in` and pass `not_in`. Property names are literal\nkeys, including dots. Registration identity defaults to `person_id`; a configured\nidentity property must be present. It counts accounts, so it should be immutable.\n\nThe same object is `posthogConfig` in REST `PATCH /api/app-profiles/:id`, MCP\n`upsert_app_profile`, and the App Profile JSON used by `sprid init`. Add\n`registration.event` and `registration.since` there; the form edits those separately.\nNo credentials or SQL belong in this object. Fetch Insights after saving and check\nits registration notes and totals against your database before trusting a funnel.\n\n## Review suspected automated traffic\n\nOpen **Web visitors → Review traffic exclusions**, or **Settings → Apps → your\napp → PostHog → Review traffic**. Inspect a UTC date range, choose a traffic\ngroup and preview its effect before saving. A spike or a shared device\nfingerprint alone does not prove that visitors are bots. **How to tell a\nscraper from an audience, and the traps in doing it, are in\n[Check whether a traffic spike is real](https://sprid.studio/docs/traffic)**\n(`sprid docs traffic`). Read that before saving a rule.\n\nSaved exclusions apply by default to Sprid’s website totals, charts, breakdowns,\nsocial attribution and weekly website counts, including the comparison period.\nThey are app-specific and date-bounded. All properties inside a rule must match;\nmatching any enabled rule excludes the event. Remaining visitors are counted\nagain as distinct people, never by subtracting overlapping group totals.\nNative app activity and registrations are unchanged. **Restore this traffic**\ndisables a rule. Original PostHog data is never changed or deleted. Raw connected\nqueries and the marketing-review event inventory remain unfiltered evidence;\nuse Insights for the corrected website figures.\n\nAgents use MCP `review_traffic`, or REST\n`POST /api/app-profiles/:ref/traffic-review?workspaceId=…` with\n`{\"start\":\"2026-09-18\",\"end\":\"2026-09-19\"}`. End dates are exclusive, UTC;\nreview ranges are at most 31 days. An optional `exclusion` previews a rule\nagainst this period and the one before it. Save approved rules through\n`upsert_app_profile` or the profile PATCH route in\n`posthogConfig.trafficExclusions`, preserving the other configuration. Sprid\nrecords the last editor and update time. The vocabulary is provider-neutral;\ncurrently only PostHog is supported.\n\n## Social traffic and clip comparisons\n\nSave the app’s website URL on its App Profile as well as the PostHog connection.\nInsights compares completed-day website sessions with recorded social view gains.\nShared bio traffic stays at channel level; only a dedicated tagged link identifies\nan individual publish. Older clips with metric activity remain candidates.\n\nCopy stable bio links and dedicated clip links from Insights. Preserve\n`utm_source`, `utm_medium`, `sprid_account` and, for dedicated links only,\n`sprid_publish` through redirects. Never rotate the shared bio link to the newest\npublish. The optional bio-page HTML export records selections separately and\nkeeps a direct app link. Host it on the saved website hostname, with your existing\nPostHog initialization.\n\nTo capture store-link clicks and explicit website outcomes, include after the\nsite’s existing PostHog initialization:\n\n```html\n<script src=\"https://sprid.studio/sprid-attribution.js\" defer></script>\n```\n\nThis adapter uses your client and consent state; it sends nothing to Sprid.\nCall `window.spridAttribution?.track('signup')` or `.track('activation')` only\nafter that action succeeds. Existing App Profile `posthogEvents.signup` and\n`posthogEvents.activation` mappings are also accepted when the events share the\narriving website session. The adapter does not add tracking to a native app or\njoin website visits to purchases. A store click is not an install.\n\nMissing outcomes stay unmeasured. Redirect-only flows need a pre-navigation\nbeacon; redirect events are counted separately from website sessions.\n`get_insights` and `sprid insights` return the same evidence as the dashboard.\n\n## If it fails\n\n- **Access denied:** check the key is active, grants your project and has both Read permissions above. Reconnect with the corrected key file.\n- **Project not found:** check the project number and host together. A US project needs the US host.\n- **Connected but no events:** check the dates and project first. Then ask your agent to check whether your app’s tracking is sending events.\n\n## Sources and verification\n\nSetup and live data reads checked on 2026-09-09.\n\n- [PostHog personal API keys](https://posthog.com/docs/api/personal-api-keys)\n- [Project identity endpoint](https://posthog.com/docs/api/projects)\n- [HogQL query endpoint](https://posthog.com/docs/api/query)\n- [SDK and framework guides](https://posthog.com/docs/libraries)\n- [React Native screen tracking](https://posthog.com/docs/libraries/react-native)\n- [Identifying users](https://posthog.com/docs/product-analytics/identify)\n- [Funnels](https://posthog.com/docs/product-analytics/funnels)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `query`, `events`, `properties`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source posthog --json\n```\n\nProject-pinned analytics. SQL is HogQL; inspect instrumentation before interpreting events. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n\nEvent-definition discovery additionally needs `event_definition:read`; property-definition discovery needs `property_definition:read`. Keep `query:read` and `project:read` for SQL and project verification. Restrict all of them to the saved project.\n",
|
|
367
|
+
"revision": "b1fa20dbfff1d9ca"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"id": "revenuecat",
|
|
371
|
+
"title": "RevenueCat",
|
|
372
|
+
"summary": "See subscription revenue and how it changes over time.",
|
|
373
|
+
"command": "sprid connect revenuecat --app myapp --key ~/keys/revenuecat-myapp.txt --project proj1ab2c3d4",
|
|
374
|
+
"url": "https://sprid.studio/docs/connect/revenuecat",
|
|
375
|
+
"sections": [
|
|
376
|
+
{
|
|
377
|
+
"id": "you-need",
|
|
378
|
+
"title": "You need",
|
|
379
|
+
"kind": "requirements",
|
|
380
|
+
"markdown": "**Admin** access to the RevenueCat project. Create a dedicated **V2 secret API key**; the app’s public key and V1 keys cannot be used here."
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"id": "click-path-apprevenuecatcom",
|
|
384
|
+
"title": "Click path (app.revenuecat.com)",
|
|
385
|
+
"kind": "steps",
|
|
386
|
+
"markdown": "1. Select your project and open **API keys → Secret API keys → New secret API key**.\n2. Name it `Sprid analytics` and select **V2**.\n3. Under **Charts metrics permissions**, set **Overview Configuration Access Level** and **Charts Configuration Access Level** to **Read only**.\n4. Under **Project configuration permissions**, set **Apps Configuration Access Level** to **Read only**. Leave everything else at **No access**.\n5. Click **Generate** and save the key to a private file such as `~/keys/revenuecat-myapp.txt`.\n\nUse a separate key and filename for each app."
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"id": "project-id",
|
|
390
|
+
"title": "Project id",
|
|
391
|
+
"kind": "identifiers",
|
|
392
|
+
"markdown": "Open **Project settings → General** and copy the full **Project ID**, such as `proj1ab2c3d4`. Use this field, not the shorter id in the dashboard address."
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"id": "then-run",
|
|
396
|
+
"title": "Then run",
|
|
397
|
+
"kind": "command",
|
|
398
|
+
"markdown": "```sh\nsprid connect revenuecat --app myapp --key ~/keys/revenuecat-myapp.txt --project proj1ab2c3d4\n```\n\nReplace `myapp`, the file path and project id with yours. Add `--workspace <slug>` if needed. Keep the key out of chat."
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"id": "how-to-check-it-worked",
|
|
402
|
+
"title": "How to check it worked",
|
|
403
|
+
"kind": "verify",
|
|
404
|
+
"markdown": "Ask your agent: “Check that Sprid can read this app’s RevenueCat overview and daily revenue history. Report any missing dates.”\n\nA saved key alone does not confirm access. An overview can work while history is unavailable; missing dates should not be treated as zero sales."
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
"id": "if-you-also-sell-on-the-web",
|
|
408
|
+
"title": "If you also sell on the web",
|
|
409
|
+
"kind": "detail",
|
|
410
|
+
"markdown": "Connect services that record separate sales. Sprid withholds combined totals when RevenueCat may include the same Stripe or Paddle sales. Separate sales also need compatible currencies and measurement definitions before addition. RevenueCat Web Billing and your own Stripe sales use separate merchant accounts."
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"id": "if-it-fails",
|
|
414
|
+
"title": "If it fails",
|
|
415
|
+
"kind": "troubleshooting",
|
|
416
|
+
"markdown": "- **Key rejected:** check it is an active V2 secret key for the intended project.\n- **Access denied or history missing:** open the key’s **More → Edit**, check all three Read only settings, then **Submit**. You can edit the existing key.\n- **Project not found:** copy the full Project ID from **Project settings → General**. The key and id must belong to the same project.\n- **Too many requests:** retry later; creating another key will not help."
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
"id": "sources-and-verification",
|
|
420
|
+
"title": "Sources and verification",
|
|
421
|
+
"kind": "sources",
|
|
422
|
+
"markdown": "Setup and live data reads checked on 2026-09-09.\n\n- [RevenueCat API keys](https://www.revenuecat.com/docs/projects/authentication)\n- [API V2 reference](https://www.revenuecat.com/docs/api-v2)"
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"id": "investigate-with-this-connection",
|
|
426
|
+
"title": "Investigate with this connection",
|
|
427
|
+
"kind": "detail",
|
|
428
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `chart_options`, `chart`, `subscriptions`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source revenuecat --json\n```\n\nPinned project. Discover chart options before selecting dimensions, filters or resolution; preserve returned measure units. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n\nCustomer subscription reads additionally need `customer_information:subscriptions:read`. They default to production; request sandbox explicitly when investigating test purchases. Chart reads keep the chart permissions described above."
|
|
429
|
+
}
|
|
430
|
+
],
|
|
431
|
+
"markdown": "# RevenueCat\n\n**What Sprid does with this:** See subscription revenue and how it changes over time.\n\n## You need\n\n**Admin** access to the RevenueCat project. Create a dedicated **V2 secret API key**; the app’s public key and V1 keys cannot be used here.\n\n## Click path (app.revenuecat.com)\n\n1. Select your project and open **API keys → Secret API keys → New secret API key**.\n2. Name it `Sprid analytics` and select **V2**.\n3. Under **Charts metrics permissions**, set **Overview Configuration Access Level** and **Charts Configuration Access Level** to **Read only**.\n4. Under **Project configuration permissions**, set **Apps Configuration Access Level** to **Read only**. Leave everything else at **No access**.\n5. Click **Generate** and save the key to a private file such as `~/keys/revenuecat-myapp.txt`.\n\nUse a separate key and filename for each app.\n\n## Project id\n\nOpen **Project settings → General** and copy the full **Project ID**, such as `proj1ab2c3d4`. Use this field, not the shorter id in the dashboard address.\n\n## Then run\n\n```sh\nsprid connect revenuecat --app myapp --key ~/keys/revenuecat-myapp.txt --project proj1ab2c3d4\n```\n\nReplace `myapp`, the file path and project id with yours. Add `--workspace <slug>` if needed. Keep the key out of chat.\n\n## How to check it worked\n\nAsk your agent: “Check that Sprid can read this app’s RevenueCat overview and daily revenue history. Report any missing dates.”\n\nA saved key alone does not confirm access. An overview can work while history is unavailable; missing dates should not be treated as zero sales.\n\n## If you also sell on the web\n\nConnect services that record separate sales. Sprid withholds combined totals when RevenueCat may include the same Stripe or Paddle sales. Separate sales also need compatible currencies and measurement definitions before addition. RevenueCat Web Billing and your own Stripe sales use separate merchant accounts.\n\n## If it fails\n\n- **Key rejected:** check it is an active V2 secret key for the intended project.\n- **Access denied or history missing:** open the key’s **More → Edit**, check all three Read only settings, then **Submit**. You can edit the existing key.\n- **Project not found:** copy the full Project ID from **Project settings → General**. The key and id must belong to the same project.\n- **Too many requests:** retry later; creating another key will not help.\n\n## Sources and verification\n\nSetup and live data reads checked on 2026-09-09.\n\n- [RevenueCat API keys](https://www.revenuecat.com/docs/projects/authentication)\n- [API V2 reference](https://www.revenuecat.com/docs/api-v2)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `chart_options`, `chart`, `subscriptions`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source revenuecat --json\n```\n\nPinned project. Discover chart options before selecting dimensions, filters or resolution; preserve returned measure units. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n\nCustomer subscription reads additionally need `customer_information:subscriptions:read`. They default to production; request sandbox explicitly when investigating test purchases. Chart reads keep the chart permissions described above.\n",
|
|
432
|
+
"revision": "5a6c59a9f37c0486"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"id": "stripe",
|
|
436
|
+
"title": "Stripe",
|
|
437
|
+
"summary": "Read revenue and subscriptions from your Stripe account.",
|
|
438
|
+
"command": "sprid connect stripe --app <slug> --key ~/keys/stripe-sprid.txt",
|
|
439
|
+
"url": "https://sprid.studio/docs/connect/stripe",
|
|
440
|
+
"sections": [
|
|
441
|
+
{
|
|
442
|
+
"id": "you-need",
|
|
443
|
+
"title": "You need",
|
|
444
|
+
"kind": "requirements",
|
|
445
|
+
"markdown": "Permission to create a **restricted API key** in Stripe. Use a live, read-only key beginning with `rk_live_`."
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"id": "click-path-dashboardstripecom",
|
|
449
|
+
"title": "Click path (dashboard.stripe.com)",
|
|
450
|
+
"kind": "steps",
|
|
451
|
+
"markdown": "1. Open [Stripe](https://dashboard.stripe.com) → **Developers → API keys → Restricted keys → Create restricted key**.\n2. Name it `Sprid`.\n3. Set these permissions to **Read**:\n - **Core → Charges** and **Account**\n - **Billing → Subscriptions**, **Invoices** and **Prices**\n4. Leave every other permission at **None**.\n5. Create the key, reveal it and save it to a private file such as `~/keys/stripe-sprid.txt`."
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
"id": "then-run",
|
|
455
|
+
"title": "Then run",
|
|
456
|
+
"kind": "command",
|
|
457
|
+
"markdown": "```\nsprid connect stripe --app <slug> --key ~/keys/stripe-sprid.txt\n```\n\nReplace `<slug>` with your Sprid app slug and use your own file path. Keep the key out of chat."
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"id": "how-to-check-it-worked",
|
|
461
|
+
"title": "How to check it worked",
|
|
462
|
+
"kind": "verify",
|
|
463
|
+
"markdown": "Ask your agent: “Read this app’s Stripe revenue through Sprid and check that it is the right account.” A saved key alone does not confirm access."
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
"id": "what-the-numbers-mean",
|
|
467
|
+
"title": "What the numbers mean",
|
|
468
|
+
"kind": "detail",
|
|
469
|
+
"markdown": "MRR estimates current active and past-due subscription prices, spreading annual subscriptions over 12 months. It excludes trials and does not apply discounts, proration or tax, so it differs from Stripe’s dashboard definition. Revenue covers 28 complete calendar days; refunds restate original charge dates. Currencies remain separate."
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"id": "if-you-also-use-revenuecat",
|
|
473
|
+
"title": "If you also use RevenueCat",
|
|
474
|
+
"kind": "detail",
|
|
475
|
+
"markdown": "If RevenueCat may already count these Stripe sales, Sprid withholds the combined total. Addition requires resolved overlap, matching currencies and compatible measurement definitions."
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"id": "if-it-fails",
|
|
479
|
+
"title": "If it fails",
|
|
480
|
+
"kind": "troubleshooting",
|
|
481
|
+
"markdown": "- **Key rejected:** check the copied value is complete and starts with `rk_live_`.\n- **Permission denied:** check all Read permissions listed above and reconnect with a corrected key.\n- **MRR is zero but sales appear:** one-off purchases contribute revenue, but do not count as recurring subscriptions."
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
"id": "sources",
|
|
485
|
+
"title": "Sources",
|
|
486
|
+
"kind": "sources",
|
|
487
|
+
"markdown": "- [Restricted API keys](https://docs.stripe.com/keys/restricted-api-keys)\n- [Analytics API and its write requirement](https://docs.stripe.com/data/analytics)\n- [Subscriptions and charges](https://docs.stripe.com/api)"
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"id": "investigate-with-this-connection",
|
|
491
|
+
"title": "Investigate with this connection",
|
|
492
|
+
"kind": "detail",
|
|
493
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `subscriptions`, `charges`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source stripe --json\n```\n\nCredential-scoped merchant account. Filter by price/customer as appropriate when several products share the account. Amounts retain currency and minor units; SQL/Stripe Analytics is not exposed. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
494
|
+
}
|
|
495
|
+
],
|
|
496
|
+
"markdown": "# Stripe\n\n**What Sprid does with this:** Read revenue and subscriptions from your Stripe account.\n\n## You need\n\nPermission to create a **restricted API key** in Stripe. Use a live, read-only key beginning with `rk_live_`.\n\n## Click path (dashboard.stripe.com)\n\n1. Open [Stripe](https://dashboard.stripe.com) → **Developers → API keys → Restricted keys → Create restricted key**.\n2. Name it `Sprid`.\n3. Set these permissions to **Read**:\n - **Core → Charges** and **Account**\n - **Billing → Subscriptions**, **Invoices** and **Prices**\n4. Leave every other permission at **None**.\n5. Create the key, reveal it and save it to a private file such as `~/keys/stripe-sprid.txt`.\n\n## Then run\n\n```\nsprid connect stripe --app <slug> --key ~/keys/stripe-sprid.txt\n```\n\nReplace `<slug>` with your Sprid app slug and use your own file path. Keep the key out of chat.\n\n## How to check it worked\n\nAsk your agent: “Read this app’s Stripe revenue through Sprid and check that it is the right account.” A saved key alone does not confirm access.\n\n## What the numbers mean\n\nMRR estimates current active and past-due subscription prices, spreading annual subscriptions over 12 months. It excludes trials and does not apply discounts, proration or tax, so it differs from Stripe’s dashboard definition. Revenue covers 28 complete calendar days; refunds restate original charge dates. Currencies remain separate.\n\n## If you also use RevenueCat\n\nIf RevenueCat may already count these Stripe sales, Sprid withholds the combined total. Addition requires resolved overlap, matching currencies and compatible measurement definitions.\n\n## If it fails\n\n- **Key rejected:** check the copied value is complete and starts with `rk_live_`.\n- **Permission denied:** check all Read permissions listed above and reconnect with a corrected key.\n- **MRR is zero but sales appear:** one-off purchases contribute revenue, but do not count as recurring subscriptions.\n\n## Sources\n\n- [Restricted API keys](https://docs.stripe.com/keys/restricted-api-keys)\n- [Analytics API and its write requirement](https://docs.stripe.com/data/analytics)\n- [Subscriptions and charges](https://docs.stripe.com/api)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `subscriptions`, `charges`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source stripe --json\n```\n\nCredential-scoped merchant account. Filter by price/customer as appropriate when several products share the account. Amounts retain currency and minor units; SQL/Stripe Analytics is not exposed. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
497
|
+
"revision": "de4639297f55afcd"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"id": "polar",
|
|
501
|
+
"title": "Polar",
|
|
502
|
+
"summary": "Read revenue and subscriptions from your Polar account.",
|
|
503
|
+
"command": "sprid connect polar --app <slug> --key ~/keys/polar-sprid.txt",
|
|
504
|
+
"url": "https://sprid.studio/docs/connect/polar",
|
|
505
|
+
"sections": [
|
|
506
|
+
{
|
|
507
|
+
"id": "you-need",
|
|
508
|
+
"title": "You need",
|
|
509
|
+
"kind": "requirements",
|
|
510
|
+
"markdown": "Access to your Polar organization’s developer settings."
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"id": "click-path-polarsh",
|
|
514
|
+
"title": "Click path (polar.sh)",
|
|
515
|
+
"kind": "steps",
|
|
516
|
+
"markdown": "1. Open your organization → **Settings → Developers**.\n2. Click **New Organization Access Token** and name it `Sprid`.\n3. Select **metrics:read** and leave other permissions off.\n4. Create the token and save it to a private file such as `~/keys/polar-sprid.txt`. It is shown only once."
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"id": "then-run",
|
|
520
|
+
"title": "Then run",
|
|
521
|
+
"kind": "command",
|
|
522
|
+
"markdown": "```\nsprid connect polar --app <slug> --key ~/keys/polar-sprid.txt\n```\n\nReplace `<slug>` with your Sprid app slug and use your own file path. If using a personal token that covers several organizations, add `--org <organization-id>` to select yours."
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
"id": "how-to-check-it-worked",
|
|
526
|
+
"title": "How to check it worked",
|
|
527
|
+
"kind": "verify",
|
|
528
|
+
"markdown": "Ask your agent: “Check that Sprid can read revenue and subscriptions for this Polar organization.” A saved token alone does not confirm access."
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
"id": "what-the-numbers-mean",
|
|
532
|
+
"title": "What the numbers mean",
|
|
533
|
+
"kind": "detail",
|
|
534
|
+
"markdown": "Sprid shows Polar’s daily revenue and current monthly recurring revenue. Polar does not supply a trial count, so that field stays blank."
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"id": "if-it-fails",
|
|
538
|
+
"title": "If it fails",
|
|
539
|
+
"kind": "troubleshooting",
|
|
540
|
+
"markdown": "- **Access denied:** create a replacement token with **metrics:read**, then reconnect.\n- **Wrong or empty results with a personal token:** add `--org <organization-id>` to the connection command."
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
"id": "sources",
|
|
544
|
+
"title": "Sources",
|
|
545
|
+
"kind": "sources",
|
|
546
|
+
"markdown": "- [Metrics endpoint](https://polar.sh/docs/api-reference/metrics/get)"
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"id": "investigate-with-this-connection",
|
|
550
|
+
"title": "Investigate with this connection",
|
|
551
|
+
"kind": "detail",
|
|
552
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `metrics`, `orders`, `subscriptions`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source polar --json\n```\n\nPinned organization. Product filters distinguish apps sold through the same organization. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
553
|
+
}
|
|
554
|
+
],
|
|
555
|
+
"markdown": "# Polar\n\n**What Sprid does with this:** Read revenue and subscriptions from your Polar account.\n\n## You need\n\nAccess to your Polar organization’s developer settings.\n\n## Click path (polar.sh)\n\n1. Open your organization → **Settings → Developers**.\n2. Click **New Organization Access Token** and name it `Sprid`.\n3. Select **metrics:read** and leave other permissions off.\n4. Create the token and save it to a private file such as `~/keys/polar-sprid.txt`. It is shown only once.\n\n## Then run\n\n```\nsprid connect polar --app <slug> --key ~/keys/polar-sprid.txt\n```\n\nReplace `<slug>` with your Sprid app slug and use your own file path. If using a personal token that covers several organizations, add `--org <organization-id>` to select yours.\n\n## How to check it worked\n\nAsk your agent: “Check that Sprid can read revenue and subscriptions for this Polar organization.” A saved token alone does not confirm access.\n\n## What the numbers mean\n\nSprid shows Polar’s daily revenue and current monthly recurring revenue. Polar does not supply a trial count, so that field stays blank.\n\n## If it fails\n\n- **Access denied:** create a replacement token with **metrics:read**, then reconnect.\n- **Wrong or empty results with a personal token:** add `--org <organization-id>` to the connection command.\n\n## Sources\n\n- [Metrics endpoint](https://polar.sh/docs/api-reference/metrics/get)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `metrics`, `orders`, `subscriptions`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source polar --json\n```\n\nPinned organization. Product filters distinguish apps sold through the same organization. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
556
|
+
"revision": "6e5eccb904cf1679"
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
"id": "lemonsqueezy",
|
|
560
|
+
"title": "Lemon Squeezy",
|
|
561
|
+
"summary": "Read sales and subscriptions from your Lemon Squeezy store.",
|
|
562
|
+
"command": "sprid connect lemonsqueezy --app <slug> --key ~/keys/lemonsqueezy-sprid.txt --store 12345",
|
|
563
|
+
"url": "https://sprid.studio/docs/connect/lemonsqueezy",
|
|
564
|
+
"sections": [
|
|
565
|
+
{
|
|
566
|
+
"id": "you-need",
|
|
567
|
+
"title": "You need",
|
|
568
|
+
"kind": "requirements",
|
|
569
|
+
"markdown": "Access to your store’s **Settings → API** page."
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"id": "click-path-applemonsqueezycom",
|
|
573
|
+
"title": "Click path (app.lemonsqueezy.com)",
|
|
574
|
+
"kind": "steps",
|
|
575
|
+
"markdown": "1. Open **Settings → API** and click **+** to create a key. Name it `Sprid`.\n2. Copy the key and save it to a private file such as `~/keys/lemonsqueezy-sprid.txt`. It is shown only once.\n3. Open **Settings → Stores**, select your store and copy its numeric id from the page address."
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
"id": "then-run",
|
|
579
|
+
"title": "Then run",
|
|
580
|
+
"kind": "command",
|
|
581
|
+
"markdown": "```\nsprid connect lemonsqueezy --app <slug> --key ~/keys/lemonsqueezy-sprid.txt --store 12345\n```\n\nReplace `<slug>` with your Sprid app slug. Use your own file path and store id; both are required."
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
"id": "how-to-check-it-worked",
|
|
585
|
+
"title": "How to check it worked",
|
|
586
|
+
"kind": "verify",
|
|
587
|
+
"markdown": "Ask your agent: “Read this store’s Lemon Squeezy sales through Sprid and confirm the store is correct.” A saved key alone does not confirm access."
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
"id": "what-the-numbers-mean",
|
|
591
|
+
"title": "What the numbers mean",
|
|
592
|
+
"kind": "detail",
|
|
593
|
+
"markdown": "Revenue covers 28 complete calendar days. Sprid combines orders with renewal/update invoices, excludes duplicate initial invoices and deducts refunds on the original purchase date. Currencies remain separate. Incomplete pagination makes the total unavailable.\n\nMRR is unavailable until a complete priced billing schedule can be established; subscription objects supply price IDs rather than the prices needed for that calculation."
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"id": "if-it-fails",
|
|
597
|
+
"title": "If it fails",
|
|
598
|
+
"kind": "troubleshooting",
|
|
599
|
+
"markdown": "- **Key rejected:** create a replacement and reconnect.\n- **Store not found:** check the store id belongs to the account that created the key.\n- **An unexpected error page appears:** retry the connection. If it continues, send the message to [Sprid support](mailto:hello@sprid.studio)."
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"id": "sources",
|
|
603
|
+
"title": "Sources",
|
|
604
|
+
"kind": "sources",
|
|
605
|
+
"markdown": "- [The store object](https://docs.lemonsqueezy.com/api/stores/the-store-object)\n- [Getting started with the API](https://docs.lemonsqueezy.com/guides/developer-guide/getting-started)"
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"id": "investigate-with-this-connection",
|
|
609
|
+
"title": "Investigate with this connection",
|
|
610
|
+
"kind": "detail",
|
|
611
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `orders`, `subscriptions` and `subscription-invoices`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source lemonsqueezy --json\n```\n\nPinned store. Product/variant filters distinguish apps in the same store. Preserve provider amounts and currencies. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
612
|
+
}
|
|
613
|
+
],
|
|
614
|
+
"markdown": "# Lemon Squeezy\n\n**What Sprid does with this:** Read sales and subscriptions from your Lemon Squeezy store.\n\n## You need\n\nAccess to your store’s **Settings → API** page.\n\n## Click path (app.lemonsqueezy.com)\n\n1. Open **Settings → API** and click **+** to create a key. Name it `Sprid`.\n2. Copy the key and save it to a private file such as `~/keys/lemonsqueezy-sprid.txt`. It is shown only once.\n3. Open **Settings → Stores**, select your store and copy its numeric id from the page address.\n\n## Then run\n\n```\nsprid connect lemonsqueezy --app <slug> --key ~/keys/lemonsqueezy-sprid.txt --store 12345\n```\n\nReplace `<slug>` with your Sprid app slug. Use your own file path and store id; both are required.\n\n## How to check it worked\n\nAsk your agent: “Read this store’s Lemon Squeezy sales through Sprid and confirm the store is correct.” A saved key alone does not confirm access.\n\n## What the numbers mean\n\nRevenue covers 28 complete calendar days. Sprid combines orders with renewal/update invoices, excludes duplicate initial invoices and deducts refunds on the original purchase date. Currencies remain separate. Incomplete pagination makes the total unavailable.\n\nMRR is unavailable until a complete priced billing schedule can be established; subscription objects supply price IDs rather than the prices needed for that calculation.\n\n## If it fails\n\n- **Key rejected:** create a replacement and reconnect.\n- **Store not found:** check the store id belongs to the account that created the key.\n- **An unexpected error page appears:** retry the connection. If it continues, send the message to [Sprid support](mailto:hello@sprid.studio).\n\n## Sources\n\n- [The store object](https://docs.lemonsqueezy.com/api/stores/the-store-object)\n- [Getting started with the API](https://docs.lemonsqueezy.com/guides/developer-guide/getting-started)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `orders`, `subscriptions` and `subscription-invoices`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source lemonsqueezy --json\n```\n\nPinned store. Product/variant filters distinguish apps in the same store. Preserve provider amounts and currencies. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
615
|
+
"revision": "119ac2c9d6a9737b"
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
"id": "paddle",
|
|
619
|
+
"title": "Paddle",
|
|
620
|
+
"summary": "Read revenue and subscriptions from your Paddle account.",
|
|
621
|
+
"command": "sprid connect paddle --app <slug> --key ~/keys/paddle-sprid.txt",
|
|
622
|
+
"url": "https://sprid.studio/docs/connect/paddle",
|
|
623
|
+
"sections": [
|
|
624
|
+
{
|
|
625
|
+
"id": "you-need",
|
|
626
|
+
"title": "You need",
|
|
627
|
+
"kind": "requirements",
|
|
628
|
+
"markdown": "Access to **Paddle Billing**. Paddle Classic keys cannot be used for this connection. Know whether you are using your live account or sandbox."
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
"id": "click-path-vendorspaddlecom",
|
|
632
|
+
"title": "Click path (vendors.paddle.com)",
|
|
633
|
+
"kind": "steps",
|
|
634
|
+
"markdown": "1. Open **Developer tools → Authentication → New API key** and name it `Sprid`.\n2. Select **transaction.read** and **subscription.read**. Leave other permissions off.\n3. Create the key and save it to a private file such as `~/keys/paddle-sprid.txt`. It is shown only once."
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
"id": "then-run",
|
|
638
|
+
"title": "Then run",
|
|
639
|
+
"kind": "command",
|
|
640
|
+
"markdown": "```\nsprid connect paddle --app <slug> --key ~/keys/paddle-sprid.txt\n```\n\nReplace `<slug>` with your Sprid app slug and use your own file path. For a sandbox key, add `--env sandbox`."
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
"id": "how-to-check-it-worked",
|
|
644
|
+
"title": "How to check it worked",
|
|
645
|
+
"kind": "verify",
|
|
646
|
+
"markdown": "Ask your agent: “Check that Sprid can read this Paddle account’s completed sales and active subscriptions.” A saved key alone does not confirm access."
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"id": "what-the-numbers-mean",
|
|
650
|
+
"title": "What the numbers mean",
|
|
651
|
+
"kind": "detail",
|
|
652
|
+
"markdown": "Revenue covers 28 complete days of gross completed transactions, including tax and before refunds, credits, chargebacks and Paddle’s fees. It will differ from your payout. MRR estimates current active subscription prices over their billing periods. Currencies remain separate; incomplete pagination makes a total unavailable."
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"id": "if-it-fails",
|
|
656
|
+
"title": "If it fails",
|
|
657
|
+
"kind": "troubleshooting",
|
|
658
|
+
"markdown": "- **Access denied:** check whether the key is for sandbox. If so, reconnect with `--env sandbox`.\n- **A permission is missing:** create a replacement key with both permissions above, then reconnect.\n- **Revenue exceeds your payout:** compare customer payments, rather than the amount left after tax and fees."
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
"id": "sources",
|
|
662
|
+
"title": "Sources",
|
|
663
|
+
"kind": "sources",
|
|
664
|
+
"markdown": "- [List transactions](https://developer.paddle.com/api-reference/transactions/list-transactions)\n- [API authentication](https://developer.paddle.com/api-reference/about/authentication)"
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
"id": "investigate-with-this-connection",
|
|
668
|
+
"title": "Investigate with this connection",
|
|
669
|
+
"kind": "detail",
|
|
670
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `transactions`, `subscriptions`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source paddle --json\n```\n\nCredential-scoped merchant account, with sandbox/live from the profile. Dates filter billed or created time as described; monetary values are minor-unit strings. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n\nSubscription investigations need `subscription.read` in addition to `transaction.read` for transaction pages. Creation-date filtering on subscriptions happens per page in Sprid; continue pagination even if a page contains no matches."
|
|
671
|
+
}
|
|
672
|
+
],
|
|
673
|
+
"markdown": "# Paddle\n\n**What Sprid does with this:** Read revenue and subscriptions from your Paddle account.\n\n## You need\n\nAccess to **Paddle Billing**. Paddle Classic keys cannot be used for this connection. Know whether you are using your live account or sandbox.\n\n## Click path (vendors.paddle.com)\n\n1. Open **Developer tools → Authentication → New API key** and name it `Sprid`.\n2. Select **transaction.read** and **subscription.read**. Leave other permissions off.\n3. Create the key and save it to a private file such as `~/keys/paddle-sprid.txt`. It is shown only once.\n\n## Then run\n\n```\nsprid connect paddle --app <slug> --key ~/keys/paddle-sprid.txt\n```\n\nReplace `<slug>` with your Sprid app slug and use your own file path. For a sandbox key, add `--env sandbox`.\n\n## How to check it worked\n\nAsk your agent: “Check that Sprid can read this Paddle account’s completed sales and active subscriptions.” A saved key alone does not confirm access.\n\n## What the numbers mean\n\nRevenue covers 28 complete days of gross completed transactions, including tax and before refunds, credits, chargebacks and Paddle’s fees. It will differ from your payout. MRR estimates current active subscription prices over their billing periods. Currencies remain separate; incomplete pagination makes a total unavailable.\n\n## If it fails\n\n- **Access denied:** check whether the key is for sandbox. If so, reconnect with `--env sandbox`.\n- **A permission is missing:** create a replacement key with both permissions above, then reconnect.\n- **Revenue exceeds your payout:** compare customer payments, rather than the amount left after tax and fees.\n\n## Sources\n\n- [List transactions](https://developer.paddle.com/api-reference/transactions/list-transactions)\n- [API authentication](https://developer.paddle.com/api-reference/about/authentication)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `transactions`, `subscriptions`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source paddle --json\n```\n\nCredential-scoped merchant account, with sandbox/live from the profile. Dates filter billed or created time as described; monetary values are minor-unit strings. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n\nSubscription investigations need `subscription.read` in addition to `transaction.read` for transaction pages. Creation-date filtering on subscriptions happens per page in Sprid; continue pagination even if a page contains no matches.\n",
|
|
674
|
+
"revision": "8aa94285843990a3"
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
"id": "cloudflare",
|
|
678
|
+
"title": "Cloudflare (optional)",
|
|
679
|
+
"summary": "Read traffic reports for your website.",
|
|
680
|
+
"command": "sprid connect cloudflare --token ~/keys/cloudflare-sprid.txt --zone 0123456789abcdef0123456789abcdef",
|
|
681
|
+
"url": "https://sprid.studio/docs/connect/cloudflare",
|
|
682
|
+
"sections": [
|
|
683
|
+
{
|
|
684
|
+
"id": "you-need",
|
|
685
|
+
"title": "You need",
|
|
686
|
+
"kind": "requirements",
|
|
687
|
+
"markdown": "Access to your domain’s Cloudflare account and permission to create a token. Enable **Web Analytics** for visitor reports; basic request counts include bots."
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"id": "click-path-dashcloudflarecom",
|
|
691
|
+
"title": "Click path (dash.cloudflare.com)",
|
|
692
|
+
"kind": "steps",
|
|
693
|
+
"markdown": "1. Open [Cloudflare](https://dash.cloudflare.com) → your profile icon → **My Profile → API Tokens**.\n2. Click **Create Token → Custom token → Get started** and name it `Sprid`.\n3. Add these **Permissions**:\n - **Zone → Analytics → Read**\n - **Account → Account Analytics → Read**\n4. Set **Zone Resources → Include → Specific zone** to your domain.\n5. Set **Account Resources → Include** to your account.\n6. Leave **Client IP Address Filtering** and **TTL** empty. Click **Continue to summary → Create Token**.\n7. Save the token to a private file, such as `~/keys/cloudflare-sprid.txt`. It is shown only once."
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"id": "zone-id",
|
|
697
|
+
"title": "Zone id",
|
|
698
|
+
"kind": "identifiers",
|
|
699
|
+
"markdown": "Open your domain → **Overview** and copy **Zone ID** and **Account ID** from the **API** card. Use the Zone ID below. Ask your agent to save the Account ID in your Sprid app profile."
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
"id": "then-run",
|
|
703
|
+
"title": "Then run",
|
|
704
|
+
"kind": "command",
|
|
705
|
+
"markdown": "```\nsprid connect cloudflare --token ~/keys/cloudflare-sprid.txt --zone 0123456789abcdef0123456789abcdef\n```\n\nReplace the file path and Zone ID with yours. Do not paste the token into chat."
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
"id": "how-to-check-it-worked",
|
|
709
|
+
"title": "How to check it worked",
|
|
710
|
+
"kind": "verify",
|
|
711
|
+
"markdown": "Run `sprid status`, then ask your agent: “Check that Sprid can read recent Cloudflare traffic for this domain.”\n\nThe check should identify the domain and say whether visitor reports or only request counts are available."
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"id": "if-it-fails",
|
|
715
|
+
"title": "If it fails",
|
|
716
|
+
"kind": "troubleshooting",
|
|
717
|
+
"markdown": "- **Access denied:** open **API Tokens → ⋯ → Edit**. Check both Read permissions and the selected domain and account.\n- **Domain not found:** use the copied Zone ID instead of the domain name.\n- **Visitor reports are empty:** enable **Analytics & Logs → Web Analytics** and check that tracking is installed on your site."
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
"id": "token-ownership-and-analytics-permissions",
|
|
721
|
+
"title": "Token ownership and analytics permissions",
|
|
722
|
+
"kind": "detail",
|
|
723
|
+
"markdown": "For a connection that stays active when you leave the team, create an account-owned token under **Manage Account → Account API Tokens** with the same permissions."
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
"id": "sources",
|
|
727
|
+
"title": "Sources",
|
|
728
|
+
"kind": "sources",
|
|
729
|
+
"markdown": "- [Create an API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/)\n- [GraphQL Analytics API token permissions](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/)\n- [Find zone and account ids](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/)\n- [Verify a token](https://developers.cloudflare.com/api/resources/user/subresources/tokens/methods/verify/)"
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
"id": "investigate-with-this-connection",
|
|
733
|
+
"title": "Investigate with this connection",
|
|
734
|
+
"kind": "detail",
|
|
735
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `rum`, `http`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source cloudflare --json\n```\n\nRUM is pinned to the saved account and website hostname. Beacon traffic is sampled and is not verified human traffic. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
736
|
+
}
|
|
737
|
+
],
|
|
738
|
+
"markdown": "# Cloudflare (optional)\n\n**What Sprid does with this:** Read traffic reports for your website.\n\n## You need\n\nAccess to your domain’s Cloudflare account and permission to create a token. Enable **Web Analytics** for visitor reports; basic request counts include bots.\n\n## Click path (dash.cloudflare.com)\n\n1. Open [Cloudflare](https://dash.cloudflare.com) → your profile icon → **My Profile → API Tokens**.\n2. Click **Create Token → Custom token → Get started** and name it `Sprid`.\n3. Add these **Permissions**:\n - **Zone → Analytics → Read**\n - **Account → Account Analytics → Read**\n4. Set **Zone Resources → Include → Specific zone** to your domain.\n5. Set **Account Resources → Include** to your account.\n6. Leave **Client IP Address Filtering** and **TTL** empty. Click **Continue to summary → Create Token**.\n7. Save the token to a private file, such as `~/keys/cloudflare-sprid.txt`. It is shown only once.\n\n## Zone id\n\nOpen your domain → **Overview** and copy **Zone ID** and **Account ID** from the **API** card. Use the Zone ID below. Ask your agent to save the Account ID in your Sprid app profile.\n\n## Then run\n\n```\nsprid connect cloudflare --token ~/keys/cloudflare-sprid.txt --zone 0123456789abcdef0123456789abcdef\n```\n\nReplace the file path and Zone ID with yours. Do not paste the token into chat.\n\n## How to check it worked\n\nRun `sprid status`, then ask your agent: “Check that Sprid can read recent Cloudflare traffic for this domain.”\n\nThe check should identify the domain and say whether visitor reports or only request counts are available.\n\n## If it fails\n\n- **Access denied:** open **API Tokens → ⋯ → Edit**. Check both Read permissions and the selected domain and account.\n- **Domain not found:** use the copied Zone ID instead of the domain name.\n- **Visitor reports are empty:** enable **Analytics & Logs → Web Analytics** and check that tracking is installed on your site.\n\n## Token ownership and analytics permissions\n\nFor a connection that stays active when you leave the team, create an account-owned token under **Manage Account → Account API Tokens** with the same permissions.\n\n## Sources\n\n- [Create an API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/)\n- [GraphQL Analytics API token permissions](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/)\n- [Find zone and account ids](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/)\n- [Verify a token](https://developers.cloudflare.com/api/resources/user/subresources/tokens/methods/verify/)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `rum`, `http`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source cloudflare --json\n```\n\nRUM is pinned to the saved account and website hostname. Beacon traffic is sampled and is not verified human traffic. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
739
|
+
"revision": "271012aedf50a897"
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
"id": "instagram",
|
|
743
|
+
"title": "Instagram",
|
|
744
|
+
"summary": "Publish approved posts to Instagram and see how they perform.",
|
|
745
|
+
"command": "sprid connect instagram --account <slug>",
|
|
746
|
+
"url": "https://sprid.studio/docs/connect/instagram",
|
|
747
|
+
"sections": [
|
|
748
|
+
{
|
|
749
|
+
"id": "you-need",
|
|
750
|
+
"title": "You need",
|
|
751
|
+
"kind": "requirements",
|
|
752
|
+
"markdown": "Creating a brand, creator or side account? Start with [Create your social accounts](https://sprid.studio/docs/connect/social-accounts).\n\n- An Instagram **Business** or **Creator** account. A Facebook Page is optional.\n- Your phone for any two-factor sign-in prompt.\n\n### Create an account first\n\nOpen [Instagram signup](https://www.instagram.com/accounts/emailsignup/), enter the intended owner email and chosen handle, then complete verification yourself. Check the resulting profile before connecting it.\n\n### Switch a personal account to professional\n\nIn Instagram, open your profile → **≡ → Settings and activity → For professionals → Account type and tools → Switch to professional account**. Pick a category, then **Creator** or **Business**. You can skip linking a Facebook Page."
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
"id": "then-run",
|
|
756
|
+
"title": "Then run",
|
|
757
|
+
"kind": "command",
|
|
758
|
+
"markdown": "```\nsprid connect instagram --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug. You can also connect from **Settings → Channels → Connect Instagram** in Sprid."
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
"id": "click-path-the-connect",
|
|
762
|
+
"title": "Click path (the connect)",
|
|
763
|
+
"kind": "steps",
|
|
764
|
+
"markdown": "1. In the browser that opens, sign in to the Instagram account you want to use. If the wrong account is signed in, sign out first.\n2. Review the access Sprid requests for publishing and reading results. Leave the requested permissions enabled.\n3. Click **Allow** to return to Sprid.\n\nFor an agent-controlled browser session, add `--no-browser` to the command and open its returned authorization link in the session for the intended Instagram account. Check the handle in the consent dialog before selecting Allow. Keep the temporary link private."
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"id": "how-to-check-it-worked",
|
|
768
|
+
"title": "How to check it worked",
|
|
769
|
+
"kind": "verify",
|
|
770
|
+
"markdown": "Run `sprid status` and check that Instagram shows the right handle as connected. Before scheduling a batch, publish a post you have reviewed and check it on Instagram."
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
"id": "if-it-fails",
|
|
774
|
+
"title": "If it fails",
|
|
775
|
+
"kind": "troubleshooting",
|
|
776
|
+
"markdown": "- **Account not eligible:** switch to Business or Creator, then reconnect.\n- **Already connected elsewhere:** first check the handle. If another account is signed in, cancel and restart with the correct login. Move a connection only when you intend to change its Sprid destination.\n- **Connection expired or permissions missing:** run the connect command again and approve the requested access.\n- **App unavailable, “Invalid Scopes” or a redirect error:** contact [Sprid support](mailto:hello@sprid.studio) with the error message. Sprid needs to resolve this; changing your account will not help.\n\n- **Long-lived token exchange fails after Allow:** authorization has not completed. Contact [Sprid support](mailto:hello@sprid.studio) with the error text. Sprid must check app access and any tester-role requirement. If Sprid invites your account, open Instagram Settings → Website permissions → Apps and websites → Tester Invites, accept Sprid-IG, then start a fresh connection. The Tester Invites tab may appear only after an invitation; do not create another Instagram account or your own Meta developer app. An error such as `Unsupported request - method type: get` does not, by itself, identify the cause."
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
"id": "sources",
|
|
780
|
+
"title": "Sources",
|
|
781
|
+
"kind": "sources",
|
|
782
|
+
"markdown": "- [Instagram API with Instagram Login](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/)\n- [Business Login for Instagram](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login)\n- [Permission descriptions and App Review requirement](https://developers.facebook.com/docs/permissions)\n- [App modes](https://developers.facebook.com/docs/development/build-and-test/app-modes)\n- [Switch to a professional account](https://creatorsupport.creatoriq.com/hc/en-us/articles/13578083261709-How-do-I-switch-from-a-Personal-to-a-Professional-Instagram-account)"
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
"id": "investigate-with-this-connection",
|
|
786
|
+
"title": "Investigate with this connection",
|
|
787
|
+
"kind": "detail",
|
|
788
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source instagram --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
789
|
+
}
|
|
790
|
+
],
|
|
791
|
+
"markdown": "# Instagram\n\n**What Sprid does with this:** Publish approved posts to Instagram and see how they perform.\n\n## You need\n\nCreating a brand, creator or side account? Start with [Create your social accounts](https://sprid.studio/docs/connect/social-accounts).\n\n- An Instagram **Business** or **Creator** account. A Facebook Page is optional.\n- Your phone for any two-factor sign-in prompt.\n\n### Create an account first\n\nOpen [Instagram signup](https://www.instagram.com/accounts/emailsignup/), enter the intended owner email and chosen handle, then complete verification yourself. Check the resulting profile before connecting it.\n\n### Switch a personal account to professional\n\nIn Instagram, open your profile → **≡ → Settings and activity → For professionals → Account type and tools → Switch to professional account**. Pick a category, then **Creator** or **Business**. You can skip linking a Facebook Page.\n\n## Then run\n\n```\nsprid connect instagram --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug. You can also connect from **Settings → Channels → Connect Instagram** in Sprid.\n\n## Click path (the connect)\n\n1. In the browser that opens, sign in to the Instagram account you want to use. If the wrong account is signed in, sign out first.\n2. Review the access Sprid requests for publishing and reading results. Leave the requested permissions enabled.\n3. Click **Allow** to return to Sprid.\n\nFor an agent-controlled browser session, add `--no-browser` to the command and open its returned authorization link in the session for the intended Instagram account. Check the handle in the consent dialog before selecting Allow. Keep the temporary link private.\n\n## How to check it worked\n\nRun `sprid status` and check that Instagram shows the right handle as connected. Before scheduling a batch, publish a post you have reviewed and check it on Instagram.\n\n## If it fails\n\n- **Account not eligible:** switch to Business or Creator, then reconnect.\n- **Already connected elsewhere:** first check the handle. If another account is signed in, cancel and restart with the correct login. Move a connection only when you intend to change its Sprid destination.\n- **Connection expired or permissions missing:** run the connect command again and approve the requested access.\n- **App unavailable, “Invalid Scopes” or a redirect error:** contact [Sprid support](mailto:hello@sprid.studio) with the error message. Sprid needs to resolve this; changing your account will not help.\n\n- **Long-lived token exchange fails after Allow:** authorization has not completed. Contact [Sprid support](mailto:hello@sprid.studio) with the error text. Sprid must check app access and any tester-role requirement. If Sprid invites your account, open Instagram Settings → Website permissions → Apps and websites → Tester Invites, accept Sprid-IG, then start a fresh connection. The Tester Invites tab may appear only after an invitation; do not create another Instagram account or your own Meta developer app. An error such as `Unsupported request - method type: get` does not, by itself, identify the cause.\n\n## Sources\n\n- [Instagram API with Instagram Login](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/)\n- [Business Login for Instagram](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login)\n- [Permission descriptions and App Review requirement](https://developers.facebook.com/docs/permissions)\n- [App modes](https://developers.facebook.com/docs/development/build-and-test/app-modes)\n- [Switch to a professional account](https://creatorsupport.creatoriq.com/hc/en-us/articles/13578083261709-How-do-I-switch-from-a-Personal-to-a-Professional-Instagram-account)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source instagram --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
792
|
+
"revision": "369429afd80634a2"
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
"id": "tiktok",
|
|
796
|
+
"title": "TikTok",
|
|
797
|
+
"summary": "Publish approved posts to TikTok, or send drafts to finish in the TikTok app.",
|
|
798
|
+
"command": "sprid connect tiktok --account <slug>",
|
|
799
|
+
"url": "https://sprid.studio/docs/connect/tiktok",
|
|
800
|
+
"sections": [
|
|
801
|
+
{
|
|
802
|
+
"id": "you-need",
|
|
803
|
+
"title": "You need",
|
|
804
|
+
"kind": "requirements",
|
|
805
|
+
"markdown": "A TikTok account you can sign in to. Make it public if you want to publish public posts."
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"id": "then-run",
|
|
809
|
+
"title": "Then run",
|
|
810
|
+
"kind": "command",
|
|
811
|
+
"markdown": "```\nsprid connect tiktok --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug."
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"id": "click-path-the-connect",
|
|
815
|
+
"title": "Click path (the connect)",
|
|
816
|
+
"kind": "steps",
|
|
817
|
+
"markdown": "1. Sign in to TikTok in the browser that opens. You can scan the QR code with your phone.\n2. Review Sprid’s requested access and click **Authorize**.\n3. Return to Sprid and check the connected handle."
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
"id": "how-to-check-it-worked",
|
|
821
|
+
"title": "How to check it worked",
|
|
822
|
+
"kind": "verify",
|
|
823
|
+
"markdown": "Run `sprid status` and check your TikTok handle. For a publishing check, choose **Only me** for a reviewed post, then find it on your TikTok profile."
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"id": "before-publishing",
|
|
827
|
+
"title": "Before publishing",
|
|
828
|
+
"kind": "detail",
|
|
829
|
+
"markdown": "Choose the audience and whether to allow comments each time. Videos also offer Duet and Stitch where your account allows them.\n\nIf a post promotes your business or another brand, complete the commercial-content disclosure. Branded content cannot use **Only me**. Review the music and branded-content terms above the publish button.\n\nThese choices apply to every post shown in a batch. Rescheduling an existing booking keeps that booking’s choices."
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
"id": "if-it-fails",
|
|
833
|
+
"title": "If it fails",
|
|
834
|
+
"kind": "troubleshooting",
|
|
835
|
+
"markdown": "- **A public post arrives as private:** use **Send as a draft** and finish publishing in TikTok. Contact [Sprid support](mailto:hello@sprid.studio) about the public-posting restriction.\n- **A publishing limit is reached:** retry later, or use the draft option if available.\n- **“Checking your TikTok account…” stays on screen:** select **Retry**. If it still fails, reconnect.\n- **Publish stays disabled:** complete the audience and disclosure choices and resolve any message shown beside the button."
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"id": "sources",
|
|
839
|
+
"title": "Sources",
|
|
840
|
+
"kind": "sources",
|
|
841
|
+
"markdown": "- [Content Posting API](https://developers.tiktok.com/doc/content-posting-api-get-started)\n- [Direct Post reference](https://developers.tiktok.com/doc/content-posting-api-reference-direct-post)\n- [Query creator info](https://developers.tiktok.com/doc/content-posting-api-reference-query-creator-info)\n- [Content Sharing Guidelines](https://developers.tiktok.com/doc/content-sharing-guidelines)\n- [Login Kit for web](https://developers.tiktok.com/doc/login-kit-web)"
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
"id": "investigate-with-this-connection",
|
|
845
|
+
"title": "Investigate with this connection",
|
|
846
|
+
"kind": "detail",
|
|
847
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source tiktok --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
848
|
+
}
|
|
849
|
+
],
|
|
850
|
+
"markdown": "# TikTok\n\n**What Sprid does with this:** Publish approved posts to TikTok, or send drafts to finish in the TikTok app.\n\n## You need\n\nA TikTok account you can sign in to. Make it public if you want to publish public posts.\n\n## Then run\n\n```\nsprid connect tiktok --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug.\n\n## Click path (the connect)\n\n1. Sign in to TikTok in the browser that opens. You can scan the QR code with your phone.\n2. Review Sprid’s requested access and click **Authorize**.\n3. Return to Sprid and check the connected handle.\n\n## How to check it worked\n\nRun `sprid status` and check your TikTok handle. For a publishing check, choose **Only me** for a reviewed post, then find it on your TikTok profile.\n\n## Before publishing\n\nChoose the audience and whether to allow comments each time. Videos also offer Duet and Stitch where your account allows them.\n\nIf a post promotes your business or another brand, complete the commercial-content disclosure. Branded content cannot use **Only me**. Review the music and branded-content terms above the publish button.\n\nThese choices apply to every post shown in a batch. Rescheduling an existing booking keeps that booking’s choices.\n\n## If it fails\n\n- **A public post arrives as private:** use **Send as a draft** and finish publishing in TikTok. Contact [Sprid support](mailto:hello@sprid.studio) about the public-posting restriction.\n- **A publishing limit is reached:** retry later, or use the draft option if available.\n- **“Checking your TikTok account…” stays on screen:** select **Retry**. If it still fails, reconnect.\n- **Publish stays disabled:** complete the audience and disclosure choices and resolve any message shown beside the button.\n\n## Sources\n\n- [Content Posting API](https://developers.tiktok.com/doc/content-posting-api-get-started)\n- [Direct Post reference](https://developers.tiktok.com/doc/content-posting-api-reference-direct-post)\n- [Query creator info](https://developers.tiktok.com/doc/content-posting-api-reference-query-creator-info)\n- [Content Sharing Guidelines](https://developers.tiktok.com/doc/content-sharing-guidelines)\n- [Login Kit for web](https://developers.tiktok.com/doc/login-kit-web)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source tiktok --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
851
|
+
"revision": "0bc53e6408514913"
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
"id": "youtube",
|
|
855
|
+
"title": "YouTube",
|
|
856
|
+
"summary": "Upload approved videos to your YouTube channel and read their results.",
|
|
857
|
+
"command": "sprid connect youtube --account <slug>",
|
|
858
|
+
"url": "https://sprid.studio/docs/connect/youtube",
|
|
859
|
+
"sections": [
|
|
860
|
+
{
|
|
861
|
+
"id": "you-need",
|
|
862
|
+
"title": "You need",
|
|
863
|
+
"kind": "requirements",
|
|
864
|
+
"markdown": "A Google account with a YouTube channel. To create a channel, open [YouTube](https://youtube.com) → your profile picture → **Create a channel**."
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
"id": "set-up-additional-channels",
|
|
868
|
+
"title": "Set up additional channels",
|
|
869
|
+
"kind": "steps",
|
|
870
|
+
"markdown": "Open [your channel list](https://www.youtube.com/channel_switcher) and verify the Google account that should own the new channels. Reuse existing channels or choose **Create a channel** for a separate brand, creator, topic or audience. See [Create your social accounts](https://sprid.studio/docs/connect/social-accounts).\n\nIf YouTube requires advanced-feature verification, the owner completes the offered video, ID or channel-history route. Submission can remain pending review. Continue other platforms, then recheck eligibility before retrying. This is separate from authorizing Sprid and was observed when creating additional channels in September 2026."
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
"id": "then-run",
|
|
874
|
+
"title": "Then run",
|
|
875
|
+
"kind": "command",
|
|
876
|
+
"markdown": "```\nsprid connect youtube --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug."
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
"id": "click-path-the-connect",
|
|
880
|
+
"title": "Click path (the connect)",
|
|
881
|
+
"kind": "steps",
|
|
882
|
+
"markdown": "1. Sign in with your Google account.\n2. Choose the channel you want to upload to, including the Brand Account channel if you use one.\n3. Review Sprid’s requested access and click **Continue**."
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
"id": "how-to-check-it-worked",
|
|
886
|
+
"title": "How to check it worked",
|
|
887
|
+
"kind": "verify",
|
|
888
|
+
"markdown": "Run `sprid status` and check the channel name. Upload a reviewed reel as private, then check **YouTube Studio → Content**."
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
"id": "if-it-fails",
|
|
892
|
+
"title": "If it fails",
|
|
893
|
+
"kind": "troubleshooting",
|
|
894
|
+
"markdown": "- **Google blocks sign-in or says Sprid is unverified:** contact [Sprid support](mailto:hello@sprid.studio) with the message.\n- **An upload is private although you chose Public:** check its visibility in **YouTube Studio → Content**. If YouTube will not let you change it, contact Sprid support.\n- **Upload limit reached:** wait before retrying. Check the post’s status in Sprid before submitting it again.\n\n- **Channel creation asks for verification:** follow YouTube Studio’s instructions as the primary owner. Keep the channel pending until approval is confirmed; repeated Sprid authorization cannot create it."
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
"id": "sources",
|
|
898
|
+
"title": "Sources",
|
|
899
|
+
"kind": "sources",
|
|
900
|
+
"markdown": "- [Feature eligibility and owner verification](https://support.google.com/youtube/answer/9891124?hl=en)\n- [Getting started](https://developers.google.com/youtube/v3/getting-started)\n- [`videos.insert` reference](https://developers.google.com/youtube/v3/docs/videos/insert)\n- [Quota and compliance audits](https://developers.google.com/youtube/v3/guides/quota_and_compliance_audits)\n- [Revision history](https://developers.google.com/youtube/v3/revision_history)"
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
"id": "investigate-with-this-connection",
|
|
904
|
+
"title": "Investigate with this connection",
|
|
905
|
+
"kind": "detail",
|
|
906
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source youtube --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
907
|
+
}
|
|
908
|
+
],
|
|
909
|
+
"markdown": "# YouTube\n\n**What Sprid does with this:** Upload approved videos to your YouTube channel and read their results.\n\n## You need\n\nA Google account with a YouTube channel. To create a channel, open [YouTube](https://youtube.com) → your profile picture → **Create a channel**.\n\n## Set up additional channels\n\nOpen [your channel list](https://www.youtube.com/channel_switcher) and verify the Google account that should own the new channels. Reuse existing channels or choose **Create a channel** for a separate brand, creator, topic or audience. See [Create your social accounts](https://sprid.studio/docs/connect/social-accounts).\n\nIf YouTube requires advanced-feature verification, the owner completes the offered video, ID or channel-history route. Submission can remain pending review. Continue other platforms, then recheck eligibility before retrying. This is separate from authorizing Sprid and was observed when creating additional channels in September 2026.\n\n## Then run\n\n```\nsprid connect youtube --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug.\n\n## Click path (the connect)\n\n1. Sign in with your Google account.\n2. Choose the channel you want to upload to, including the Brand Account channel if you use one.\n3. Review Sprid’s requested access and click **Continue**.\n\n## How to check it worked\n\nRun `sprid status` and check the channel name. Upload a reviewed reel as private, then check **YouTube Studio → Content**.\n\n## If it fails\n\n- **Google blocks sign-in or says Sprid is unverified:** contact [Sprid support](mailto:hello@sprid.studio) with the message.\n- **An upload is private although you chose Public:** check its visibility in **YouTube Studio → Content**. If YouTube will not let you change it, contact Sprid support.\n- **Upload limit reached:** wait before retrying. Check the post’s status in Sprid before submitting it again.\n\n- **Channel creation asks for verification:** follow YouTube Studio’s instructions as the primary owner. Keep the channel pending until approval is confirmed; repeated Sprid authorization cannot create it.\n\n## Sources\n\n- [Feature eligibility and owner verification](https://support.google.com/youtube/answer/9891124?hl=en)\n- [Getting started](https://developers.google.com/youtube/v3/getting-started)\n- [`videos.insert` reference](https://developers.google.com/youtube/v3/docs/videos/insert)\n- [Quota and compliance audits](https://developers.google.com/youtube/v3/guides/quota_and_compliance_audits)\n- [Revision history](https://developers.google.com/youtube/v3/revision_history)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source youtube --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
910
|
+
"revision": "f9cab3463a986a59"
|
|
911
|
+
},
|
|
912
|
+
{
|
|
913
|
+
"id": "linkedin",
|
|
914
|
+
"title": "LinkedIn",
|
|
915
|
+
"summary": "Publish approved carousels to LinkedIn as swipeable document posts.",
|
|
916
|
+
"command": "sprid connect linkedin --account <slug>",
|
|
917
|
+
"url": "https://sprid.studio/docs/connect/linkedin",
|
|
918
|
+
"sections": [
|
|
919
|
+
{
|
|
920
|
+
"id": "you-need",
|
|
921
|
+
"title": "You need",
|
|
922
|
+
"kind": "requirements",
|
|
923
|
+
"markdown": "A LinkedIn account. Check the connected destination before publishing: Company Page availability depends on Sprid’s LinkedIn approval. A Page also requires **Super admin** or **Content admin** access."
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
"id": "then-run",
|
|
927
|
+
"title": "Then run",
|
|
928
|
+
"kind": "command",
|
|
929
|
+
"markdown": "```\nsprid connect linkedin --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug."
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
"id": "click-path-the-connect",
|
|
933
|
+
"title": "Click path (the connect)",
|
|
934
|
+
"kind": "steps",
|
|
935
|
+
"markdown": "1. Sign in to LinkedIn in the browser that opens.\n2. Review the access Sprid requests and click **Allow**.\n3. Return to Sprid and check the connected name."
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
"id": "how-to-check-it-worked",
|
|
939
|
+
"title": "How to check it worked",
|
|
940
|
+
"kind": "verify",
|
|
941
|
+
"markdown": "Run `sprid status` and confirm the destination. After publishing a reviewed carousel, open LinkedIn and check the document post."
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
"id": "if-it-fails",
|
|
945
|
+
"title": "If it fails",
|
|
946
|
+
"kind": "troubleshooting",
|
|
947
|
+
"markdown": "- **Company Page missing:** ask its Super admin to check your role under **Page → Settings → Manage admins**. Contact [Sprid support](mailto:hello@sprid.studio) if Page publishing is unavailable.\n- **Access denied:** reconnect, then check you still have permission to publish to the destination.\n- **Connection expiring or expired:** run the connect command again."
|
|
948
|
+
},
|
|
949
|
+
{
|
|
950
|
+
"id": "sources",
|
|
951
|
+
"title": "Sources",
|
|
952
|
+
"kind": "sources",
|
|
953
|
+
"markdown": "- [Share on LinkedIn](https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin)\n- [Posts API permissions](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api)\n- [Documents API](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/documents-api)"
|
|
954
|
+
},
|
|
955
|
+
{
|
|
956
|
+
"id": "investigate-with-this-connection",
|
|
957
|
+
"title": "Investigate with this connection",
|
|
958
|
+
"kind": "detail",
|
|
959
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source linkedin --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
960
|
+
}
|
|
961
|
+
],
|
|
962
|
+
"markdown": "# LinkedIn\n\n**What Sprid does with this:** Publish approved carousels to LinkedIn as swipeable document posts.\n\n## You need\n\nA LinkedIn account. Check the connected destination before publishing: Company Page availability depends on Sprid’s LinkedIn approval. A Page also requires **Super admin** or **Content admin** access.\n\n## Then run\n\n```\nsprid connect linkedin --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug.\n\n## Click path (the connect)\n\n1. Sign in to LinkedIn in the browser that opens.\n2. Review the access Sprid requests and click **Allow**.\n3. Return to Sprid and check the connected name.\n\n## How to check it worked\n\nRun `sprid status` and confirm the destination. After publishing a reviewed carousel, open LinkedIn and check the document post.\n\n## If it fails\n\n- **Company Page missing:** ask its Super admin to check your role under **Page → Settings → Manage admins**. Contact [Sprid support](mailto:hello@sprid.studio) if Page publishing is unavailable.\n- **Access denied:** reconnect, then check you still have permission to publish to the destination.\n- **Connection expiring or expired:** run the connect command again.\n\n## Sources\n\n- [Share on LinkedIn](https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin)\n- [Posts API permissions](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api)\n- [Documents API](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/documents-api)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source linkedin --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
963
|
+
"revision": "983ed80b263badc6"
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
"id": "facebook",
|
|
967
|
+
"title": "Facebook Page",
|
|
968
|
+
"summary": "Publish approved posts to your Facebook Page and see their results.",
|
|
969
|
+
"command": "sprid connect facebook --account <slug>",
|
|
970
|
+
"url": "https://sprid.studio/docs/connect/facebook",
|
|
971
|
+
"sections": [
|
|
972
|
+
{
|
|
973
|
+
"id": "you-need",
|
|
974
|
+
"title": "You need",
|
|
975
|
+
"kind": "requirements",
|
|
976
|
+
"markdown": "A Facebook **Page** you can publish to. Check **Professional dashboard → Page access** for **Facebook access** or **task access** that includes **Content**. Personal profiles cannot be connected for publishing. Instagram does not need to be linked.\n\nNeed to create or organize Pages first? Follow [Create your social accounts](https://sprid.studio/docs/connect/social-accounts). Portfolio ownership is a separate check from a successful Sprid connection."
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
"id": "then-run",
|
|
980
|
+
"title": "Then run",
|
|
981
|
+
"kind": "command",
|
|
982
|
+
"markdown": "```\nsprid connect facebook --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug."
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
"id": "click-path-the-connect",
|
|
986
|
+
"title": "Click path (the connect)",
|
|
987
|
+
"kind": "steps",
|
|
988
|
+
"markdown": "1. Sign in to Facebook with the profile that manages your Page.\n2. Select the Page you want to connect and leave the requested permissions enabled.\n3. Click **Continue / Done** to return to Sprid.\n4. If Sprid lists several Pages, choose one by rerunning the command with `--page <id>`, using the id shown in the message."
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
"id": "how-to-check-it-worked",
|
|
992
|
+
"title": "How to check it worked",
|
|
993
|
+
"kind": "verify",
|
|
994
|
+
"markdown": "Run `sprid status` and check the connected Page’s name. When you publish a reviewed post, check that it appears on that Page."
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
"id": "if-it-fails",
|
|
998
|
+
"title": "If it fails",
|
|
999
|
+
"kind": "troubleshooting",
|
|
1000
|
+
"markdown": "- **No Pages found:** check your Page access, reconnect and select the Page in Facebook’s chooser.\n- **Permission missing:** reconnect and approve all requested permissions.\n- **Page already connected:** check that you selected the intended Page. Each Page connects to one Sprid account; disconnect the existing connection only if you intentionally want to move that Page.\n- **“Invalid Scopes”, app unavailable or “URL blocked”:** contact [Sprid support](mailto:hello@sprid.studio). These need a fix from Sprid."
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
"id": "sources",
|
|
1004
|
+
"title": "Sources",
|
|
1005
|
+
"kind": "sources",
|
|
1006
|
+
"markdown": "- [Pages API getting started](https://developers.facebook.com/docs/pages-api/getting-started)\n- [Permission descriptions and review requirements](https://developers.facebook.com/docs/permissions)\n- [App modes](https://developers.facebook.com/docs/development/build-and-test/app-modes)\n- [Facebook access vs task access on the new Pages experience](https://www.facebook.com/business/help/582754542592549)"
|
|
1007
|
+
},
|
|
1008
|
+
{
|
|
1009
|
+
"id": "investigate-with-this-connection",
|
|
1010
|
+
"title": "Investigate with this connection",
|
|
1011
|
+
"kind": "detail",
|
|
1012
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source facebook --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
1013
|
+
}
|
|
1014
|
+
],
|
|
1015
|
+
"markdown": "# Facebook Page\n\n**What Sprid does with this:** Publish approved posts to your Facebook Page and see their results.\n\n## You need\n\nA Facebook **Page** you can publish to. Check **Professional dashboard → Page access** for **Facebook access** or **task access** that includes **Content**. Personal profiles cannot be connected for publishing. Instagram does not need to be linked.\n\nNeed to create or organize Pages first? Follow [Create your social accounts](https://sprid.studio/docs/connect/social-accounts). Portfolio ownership is a separate check from a successful Sprid connection.\n\n## Then run\n\n```\nsprid connect facebook --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug.\n\n## Click path (the connect)\n\n1. Sign in to Facebook with the profile that manages your Page.\n2. Select the Page you want to connect and leave the requested permissions enabled.\n3. Click **Continue / Done** to return to Sprid.\n4. If Sprid lists several Pages, choose one by rerunning the command with `--page <id>`, using the id shown in the message.\n\n## How to check it worked\n\nRun `sprid status` and check the connected Page’s name. When you publish a reviewed post, check that it appears on that Page.\n\n## If it fails\n\n- **No Pages found:** check your Page access, reconnect and select the Page in Facebook’s chooser.\n- **Permission missing:** reconnect and approve all requested permissions.\n- **Page already connected:** check that you selected the intended Page. Each Page connects to one Sprid account; disconnect the existing connection only if you intentionally want to move that Page.\n- **“Invalid Scopes”, app unavailable or “URL blocked”:** contact [Sprid support](mailto:hello@sprid.studio). These need a fix from Sprid.\n\n## Sources\n\n- [Pages API getting started](https://developers.facebook.com/docs/pages-api/getting-started)\n- [Permission descriptions and review requirements](https://developers.facebook.com/docs/permissions)\n- [App modes](https://developers.facebook.com/docs/development/build-and-test/app-modes)\n- [Facebook access vs task access on the new Pages experience](https://www.facebook.com/business/help/582754542592549)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source facebook --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
1016
|
+
"revision": "0e61f4caa24da0e1"
|
|
1017
|
+
},
|
|
1018
|
+
{
|
|
1019
|
+
"id": "x",
|
|
1020
|
+
"title": "X",
|
|
1021
|
+
"summary": "Publish approved posts to X and see how they perform.",
|
|
1022
|
+
"command": "sprid connect x --account <slug>",
|
|
1023
|
+
"url": "https://sprid.studio/docs/connect/x",
|
|
1024
|
+
"sections": [
|
|
1025
|
+
{
|
|
1026
|
+
"id": "you-need",
|
|
1027
|
+
"title": "You need",
|
|
1028
|
+
"kind": "requirements",
|
|
1029
|
+
"markdown": "An X account you can sign in to. Sprid handles the developer connection."
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
"id": "then-run",
|
|
1033
|
+
"title": "Then run",
|
|
1034
|
+
"kind": "command",
|
|
1035
|
+
"markdown": "```\nsprid connect x --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug."
|
|
1036
|
+
},
|
|
1037
|
+
{
|
|
1038
|
+
"id": "click-path-the-connect",
|
|
1039
|
+
"title": "Click path (the connect)",
|
|
1040
|
+
"kind": "steps",
|
|
1041
|
+
"markdown": "1. Sign in to the X account you want to use.\n2. Review Sprid’s requested access and click **Authorize app**.\n3. Return to Sprid and check the connected handle."
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
"id": "how-to-check-it-worked",
|
|
1045
|
+
"title": "How to check it worked",
|
|
1046
|
+
"kind": "verify",
|
|
1047
|
+
"markdown": "Run `sprid status` and confirm the handle. After publishing a reviewed post, check it on X."
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
"id": "the-caption-is-its-own-field",
|
|
1051
|
+
"title": "The caption is its own field",
|
|
1052
|
+
"kind": "detail",
|
|
1053
|
+
"markdown": "Keep the **X caption** within **280 characters**. If the box is empty, Sprid uses your shared caption. An overlong caption must be shortened before publishing.\n\nCarousels with more than four images publish as a thread, with the caption on the first post."
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
"id": "if-it-fails",
|
|
1057
|
+
"title": "If it fails",
|
|
1058
|
+
"kind": "troubleshooting",
|
|
1059
|
+
"markdown": "- **Connection expired or refresh failed:** run the connect command again.\n- **Access denied after reconnecting:** contact [Sprid support](mailto:hello@sprid.studio) with the error message.\n- **Publishing limit reached:** check the post’s status and retry when the limit resets."
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
"id": "sources",
|
|
1063
|
+
"title": "Sources",
|
|
1064
|
+
"kind": "sources",
|
|
1065
|
+
"markdown": "- [OAuth 2.0 authorization code with PKCE](https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/authorization-code)\n- [Create a Post](https://docs.x.com/x-api/posts/create-post)\n- [Chunked media upload](https://docs.x.com/x-api/media/quickstart/media-upload-chunked)"
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
"id": "investigate-with-this-connection",
|
|
1069
|
+
"title": "Investigate with this connection",
|
|
1070
|
+
"kind": "detail",
|
|
1071
|
+
"markdown": "Your agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source x --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification."
|
|
1072
|
+
}
|
|
1073
|
+
],
|
|
1074
|
+
"markdown": "# X\n\n**What Sprid does with this:** Publish approved posts to X and see how they perform.\n\n## You need\n\nAn X account you can sign in to. Sprid handles the developer connection.\n\n## Then run\n\n```\nsprid connect x --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug.\n\n## Click path (the connect)\n\n1. Sign in to the X account you want to use.\n2. Review Sprid’s requested access and click **Authorize app**.\n3. Return to Sprid and check the connected handle.\n\n## How to check it worked\n\nRun `sprid status` and confirm the handle. After publishing a reviewed post, check it on X.\n\n## The caption is its own field\n\nKeep the **X caption** within **280 characters**. If the box is empty, Sprid uses your shared caption. An overlong caption must be shortened before publishing.\n\nCarousels with more than four images publish as a thread, with the caption on the first post.\n\n## If it fails\n\n- **Connection expired or refresh failed:** run the connect command again.\n- **Access denied after reconnecting:** contact [Sprid support](mailto:hello@sprid.studio) with the error message.\n- **Publishing limit reached:** check the post’s status and retry when the limit resets.\n\n## Sources\n\n- [OAuth 2.0 authorization code with PKCE](https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/authorization-code)\n- [Create a Post](https://docs.x.com/x-api/posts/create-post)\n- [Chunked media upload](https://docs.x.com/x-api/media/quickstart/media-upload-chunked)\n\n## Investigate with this connection\n\nYour agent can use `list_marketing_queries` and `query_marketing_source` for `posts`, `comments`. Discover the exact parameters and required setup with:\n\n```sh\nsprid marketing-review capabilities --app <slug> --source x --json\n```\n\nQueries Sprid’s stored publishes, metric snapshots and inbox for the linked content account. No live platform sync or paid API read. Missing metrics are unmeasured; this does not expose the platform’s entire API. See [connected queries](https://sprid.studio/docs/queries) for the shared workflow. Extra operations may need additional read permissions; a stored key alone is not live verification.\n",
|
|
1075
|
+
"revision": "d7675df2049b1d47"
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
"id": "pinterest",
|
|
1079
|
+
"title": "Pinterest",
|
|
1080
|
+
"summary": "Publish the Pins you select to the right boards, keep their destination links intact and read their results when analytics access is available.",
|
|
1081
|
+
"command": "sprid connect pinterest --account <slug>",
|
|
1082
|
+
"url": "https://sprid.studio/docs/connect/pinterest",
|
|
1083
|
+
"sections": [
|
|
1084
|
+
{
|
|
1085
|
+
"id": "you-need",
|
|
1086
|
+
"title": "You need",
|
|
1087
|
+
"kind": "requirements",
|
|
1088
|
+
"markdown": "- A Pinterest account you can sign in to. A free Pinterest business account is recommended because Pinterest Analytics requires one.\n- Access to the Sprid account that will own this channel.\n- A board topic in mind. A specific board gives Pinterest and people useful context about the Pin; Sprid can create it during publishing.\n\nYou do **not** need to create a Pinterest developer app, request API access or copy a token. Sprid owns the developer integration; you only authorize your own Pinterest account."
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"id": "then-run",
|
|
1092
|
+
"title": "Then run",
|
|
1093
|
+
"kind": "command",
|
|
1094
|
+
"markdown": "```sh\nsprid connect pinterest --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug."
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
"id": "click-path-the-connect",
|
|
1098
|
+
"title": "Click path (the connect)",
|
|
1099
|
+
"kind": "steps",
|
|
1100
|
+
"markdown": "1. In Sprid, open **Settings → Accounts → [account] → Pinterest**.\n2. Select **Continue with Pinterest**.\n3. Check the Pinterest identity in the browser that opens. Sign out first if it is the wrong account.\n4. Review the access Sprid requests, then authorize Sprid.\n5. Return to Sprid and confirm the connected Pinterest name.\n6. Open a post, select **Publish → Pinterest**, then confirm the intended destination in the **Board** picker. If none fits, select **Create board**, name it and choose whether it is public or secret. Sprid selects the new board automatically.\n\nConnecting one Pinterest account does not connect another account signed in under the same browser. Repeat the command for each Sprid account and check the destination every time."
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
"id": "check-the-connection",
|
|
1104
|
+
"title": "Check the connection",
|
|
1105
|
+
"kind": "verify",
|
|
1106
|
+
"markdown": "Run `sprid status` and confirm that Pinterest shows the intended account. Open a draft Pin, select **Publish → Pinterest**, and confirm that its intended board appears before approving any schedule.\n\nThe first public Pin is the final check: after it publishes, open Pinterest while signed out or from another account and confirm the Pin, board, visual, title and destination. A successful API response alone does not prove public visibility."
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
"id": "trial-and-standard-access",
|
|
1110
|
+
"title": "Trial and Standard access",
|
|
1111
|
+
"kind": "detail",
|
|
1112
|
+
"markdown": "Pinterest gives developer integrations Trial access for testing and Standard access for production. Sprid lets you connect an account and browse its boards while its app has Trial access, but it refuses both publishing and scheduling. Publishing becomes available only after **Sprid’s** Pinterest app has Standard access.\n\nThis is Sprid’s operational approval, not an application each customer completes. If Sprid reports that Pinterest publishing requires Standard access, keep preparing and reviewing drafts, but do not treat them as booked. Reconnecting your account will not change the access tier. Follow the status message or contact Sprid support."
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
"id": "prepare-the-account",
|
|
1116
|
+
"title": "Prepare the account",
|
|
1117
|
+
"kind": "detail",
|
|
1118
|
+
"markdown": "Use a business account when you need analytics. Create a small set of specific boards around topics people actually search for, such as “Small apartment viewing checklist” instead of “Inspiration”. Board names, descriptions and the Pins saved to them help establish context.\n\nClaim an owned website in Pinterest when possible. Claiming associates Pins from that site with the profile and expands website analytics. One website can be claimed by only one Pinterest account, so decide which market or brand account owns it before connecting several accounts in Sprid.\n\nRead [Pinterest content and publishing](https://sprid.studio/docs/pinterest) before preparing the first batch."
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
"id": "if-it-fails",
|
|
1122
|
+
"title": "If it fails",
|
|
1123
|
+
"kind": "troubleshooting",
|
|
1124
|
+
"markdown": "- **“Pinterest is unavailable until API credentials and an access tier are configured”:** this Sprid deployment is not ready for Pinterest. The customer does not create a developer app or provide credentials; follow Sprid’s availability status or contact support.\n- **Wrong Pinterest account connected:** disconnect it in Sprid, sign out of Pinterest in that browser, then run the command again and check the identity before authorizing.\n- **“No Pinterest boards yet”:** create one from the board picker. If Sprid asks for board permission, reconnect Pinterest once; connections made before board creation support do not carry the required write scope.\n- **Existing boards are missing:** reconnect once, then contact [Sprid support](mailto:hello@sprid.studio) with the account name and error message if they still do not appear.\n- **Access denied:** confirm that the Pinterest account is active and that you completed the consent screen. Retry once; if Pinterest still refuses access, contact Sprid support.\n- **Publishing or scheduling requires Standard access:** the account can remain connected and its boards can still be selected during setup. Sprid will not create Trial-access Pins. Only Sprid can resolve its developer access tier.\n- **Analytics unavailable:** use a Pinterest business account and check that the Pin is public. Treat unavailable data as unavailable, never as zero."
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
"id": "sources",
|
|
1128
|
+
"title": "Sources",
|
|
1129
|
+
"kind": "sources",
|
|
1130
|
+
"markdown": "- [Pinterest developer access tiers](https://developer.pinterest.com/docs/key-concepts/access-tiers/)\n- [Pinterest developer guidelines](https://policy.pinterest.com/en/developer-guidelines)\n- [Claim your website](https://help.pinterest.com/en/business/article/claim-your-website)\n- [Pinterest Analytics](https://help.pinterest.com/en/business/article/pinterest-analytics)"
|
|
1131
|
+
}
|
|
1132
|
+
],
|
|
1133
|
+
"markdown": "# Pinterest\n\n**What Sprid does with this:** Publish the Pins you select to the right boards, keep their destination links intact and read their results when analytics access is available.\n\n## You need\n\n- A Pinterest account you can sign in to. A free Pinterest business account is recommended because Pinterest Analytics requires one.\n- Access to the Sprid account that will own this channel.\n- A board topic in mind. A specific board gives Pinterest and people useful context about the Pin; Sprid can create it during publishing.\n\nYou do **not** need to create a Pinterest developer app, request API access or copy a token. Sprid owns the developer integration; you only authorize your own Pinterest account.\n\n## Then run\n\n```sh\nsprid connect pinterest --account <slug>\n```\n\nReplace `<slug>` with your Sprid account slug.\n\n## Click path (the connect)\n\n1. In Sprid, open **Settings → Accounts → [account] → Pinterest**.\n2. Select **Continue with Pinterest**.\n3. Check the Pinterest identity in the browser that opens. Sign out first if it is the wrong account.\n4. Review the access Sprid requests, then authorize Sprid.\n5. Return to Sprid and confirm the connected Pinterest name.\n6. Open a post, select **Publish → Pinterest**, then confirm the intended destination in the **Board** picker. If none fits, select **Create board**, name it and choose whether it is public or secret. Sprid selects the new board automatically.\n\nConnecting one Pinterest account does not connect another account signed in under the same browser. Repeat the command for each Sprid account and check the destination every time.\n\n## Check the connection\n\nRun `sprid status` and confirm that Pinterest shows the intended account. Open a draft Pin, select **Publish → Pinterest**, and confirm that its intended board appears before approving any schedule.\n\nThe first public Pin is the final check: after it publishes, open Pinterest while signed out or from another account and confirm the Pin, board, visual, title and destination. A successful API response alone does not prove public visibility.\n\n## Trial and Standard access\n\nPinterest gives developer integrations Trial access for testing and Standard access for production. Sprid lets you connect an account and browse its boards while its app has Trial access, but it refuses both publishing and scheduling. Publishing becomes available only after **Sprid’s** Pinterest app has Standard access.\n\nThis is Sprid’s operational approval, not an application each customer completes. If Sprid reports that Pinterest publishing requires Standard access, keep preparing and reviewing drafts, but do not treat them as booked. Reconnecting your account will not change the access tier. Follow the status message or contact Sprid support.\n\n## Prepare the account\n\nUse a business account when you need analytics. Create a small set of specific boards around topics people actually search for, such as “Small apartment viewing checklist” instead of “Inspiration”. Board names, descriptions and the Pins saved to them help establish context.\n\nClaim an owned website in Pinterest when possible. Claiming associates Pins from that site with the profile and expands website analytics. One website can be claimed by only one Pinterest account, so decide which market or brand account owns it before connecting several accounts in Sprid.\n\nRead [Pinterest content and publishing](https://sprid.studio/docs/pinterest) before preparing the first batch.\n\n## If it fails\n\n- **“Pinterest is unavailable until API credentials and an access tier are configured”:** this Sprid deployment is not ready for Pinterest. The customer does not create a developer app or provide credentials; follow Sprid’s availability status or contact support.\n- **Wrong Pinterest account connected:** disconnect it in Sprid, sign out of Pinterest in that browser, then run the command again and check the identity before authorizing.\n- **“No Pinterest boards yet”:** create one from the board picker. If Sprid asks for board permission, reconnect Pinterest once; connections made before board creation support do not carry the required write scope.\n- **Existing boards are missing:** reconnect once, then contact [Sprid support](mailto:hello@sprid.studio) with the account name and error message if they still do not appear.\n- **Access denied:** confirm that the Pinterest account is active and that you completed the consent screen. Retry once; if Pinterest still refuses access, contact Sprid support.\n- **Publishing or scheduling requires Standard access:** the account can remain connected and its boards can still be selected during setup. Sprid will not create Trial-access Pins. Only Sprid can resolve its developer access tier.\n- **Analytics unavailable:** use a Pinterest business account and check that the Pin is public. Treat unavailable data as unavailable, never as zero.\n\n## Sources\n\n- [Pinterest developer access tiers](https://developer.pinterest.com/docs/key-concepts/access-tiers/)\n- [Pinterest developer guidelines](https://policy.pinterest.com/en/developer-guidelines)\n- [Claim your website](https://help.pinterest.com/en/business/article/claim-your-website)\n- [Pinterest Analytics](https://help.pinterest.com/en/business/article/pinterest-analytics)\n",
|
|
1134
|
+
"revision": "e2c1b334eb3e495e"
|
|
1135
|
+
}
|
|
1136
|
+
];
|
|
1137
|
+
export const CONTENT_GUIDES = [
|
|
1138
|
+
{
|
|
1139
|
+
"id": "chat",
|
|
1140
|
+
"title": "Use Sprid in chat",
|
|
1141
|
+
"summary": "Take an app from setup to a reviewed post and confirmed delivery using Sprid MCP and your browser. No CLI or installed skills are required for this flow.",
|
|
1142
|
+
"url": "https://sprid.studio/docs/chat",
|
|
1143
|
+
"markdown": "# Use Sprid in chat\n\n**What this guide does:** Take an app from setup to a reviewed post and confirmed delivery using Sprid MCP and your browser. No CLI or installed skills are required for this flow.\n\nRead [one marketing plan](../../../references/guided-marketing.md). Begin with `get_marketing_plan` when available and reuse its prepared artifact, accepted guidance and exact continuation. A browser user can start discovery from a website or store URL without creating a social account.\n\n## Connect Sprid via MCP\n\nChoose your chat at `https://sprid.studio/start#chat` and follow its connection steps, then tell your connected agent what you want to make. You do not need to learn the tool names below. They tell the agent how to continue: check capabilities, retrieve the relevant guide, follow the returned next action and ask you for missing inputs or approval. Setup should introduce only the connection or tool your current task needs.\n\nAdd `https://api.sprid.studio/api/mcp?surface=core` in your chat application's remote MCP connection settings. Sign in to Sprid and authorize the intended workspace. A host may call this an app, connector or integration. **Sprid MCP** is the remote service behind it. Sprid skills supply optional workflow instructions; the plugin bundles those skills and the MCP configuration. Sprid CLI adds terminal access and local production.\n\nCall `get_capabilities`, then `list_apps` and `list_accounts`. Reuse existing records. If your app is missing, describe it or supply its website/store URL, confirm its identity and create its App Profile using `upsert_app_profile`. A content account owns its voice and media; a channel is the exact social destination. Use the dashboard's account setup if one is missing. Never choose a handle just because it is first in a list.\n\n## Connect the destination\n\nRead `get_documentation` with the platform name. Use `connect_channel` and open its returned OAuth link in the browser. The person completes consent; `channel_status` checks the saved result. The CLI is optional.\n\nFor analytics or store credentials, open the secure App Profile form at `https://app.sprid.studio/settings/app-profiles`. Select the app and service, enter its identifiers and choose the key file or paste the key into that form. Never put credentials in chat, tool arguments or generated reports. `get_marketing_review` performs a live read; a saved-key indicator establishes configuration only.\n\n## Use images or a finished video\n\nDraft the copy in your current chat, using the content account's voice and the intended platform. Ordinary drafting does not require an additional Sprid model key.\n\nIf your host exposes the selected files, use `import_assets` with its file references. Each file has `download_url`, `file_id`, and optionally `mime_type` and `file_name`. Public HTTPS URLs and existing `{kind, id}` library references are also accepted. The limit is 32 MiB per imported file. PNG, JPEG, WebP and finished MP4 are supported. The result reports each position independently; retry missing files before assembling the full post. Files are copied to the selected account and deduplicated by bytes. Temporary download URLs are not retained as provenance.\n\nFor an image generated in ChatGPT, use the existing result when the host exposes a transferable file. Direct transfer of every generated-image type is unverified. If the host cannot transfer an image, download it and use the browser upload fallback. Do not ask the agent to recreate the image or transcribe binary data. A `sandbox:` URL or a local path cannot be fetched by remote MCP.\n\nFallback: call `create_upload_session` with the content account and a new UUID `requestId`. Open its authenticated browser link, select the files, then return to chat. Read `get_studio_job` with the returned ID. Its result keys are zero-based positions. The same session and asset IDs work in another chat client. Existing files incur no image-generation charge.\n\n## Create and review the post\n\nUse `create_post_from_assets` with a new UUID `requestId`, account, ordered `{kind, id}` assets, captions and aspect ratio. Keep the ID and inputs when retrying a lost response. `presentation: \"finished\"` preserves artwork without text overlays or added music; images fit inside the chosen output canvas, which can add margins. `presentation: \"editable\"` allows `text` and `subtitle` on image slides. One finished video becomes one reel. Never mix a finished video with image slides in this operation.\n\nRead the draft with `get_post`; edit captions using `update_post` and slide content using `update_slide` or `batch_update_slides`. Call `preview_post`. Inspect every returned slide or the video, and check captions, order, crop and legibility. Links work even when your host cannot show an embedded preview. A preview is not publication approval.\n\nFor photos or text that need to become a reel, inspect `get_capabilities` for hosted creation. `create_reel` accepts ordered scenes with `imageId`, `text` and `durationMs`, up to 120 seconds. It creates a silent finished MP4. Check `spend_status`, explain the render charge (3 cents per started render minute or the plan allowance), and obtain authorization before `confirmed: true`. Save its job ID and read `get_studio_job`; a retry with the same ID never starts a second render. A stopped job reports `needs_attention` rather than silently charging another attempt. Custom app capture and arbitrary local builds remain external inputs; upload their finished files.\n\n## Approve delivery and read the receipt\n\nOpen the returned `/p/<postId>` review link. The person reviews the actual media and captions, chooses exact channels and time, and completes platform-specific choices. TikTok privacy and interaction choices have no defaults. The existing posting screen owns those requirements. An agent-supplied confirmation flag is not evidence of a human click.\n\nAfter approval, read `get_publication_status`. Keep draft, scheduled, failed and delivered states separate. Report delivery only with its platform receipt. Read a failure before retrying; never repeat a publishing call merely because a response was lost.\n\nFor results, read the `marketing-review` guide through `get_documentation`. Return to the same app/account and post IDs across clients. Call `next_actions` for the next relevant need; an empty `verb` means follow its browser link.\n\n## Limits and troubleshooting\n\n- An inaccessible attachment needs the browser upload page, not a CLI installation.\n- A missing account or service needs secure dashboard setup. Never paste credentials into MCP.\n- Check current capabilities before promising hosted creation. App binaries, native simulator captures and arbitrary repository scripts still run outside remote MCP.\n- Store screenshot composition and store release commands remain explicit local capabilities unless `get_capabilities` reports a hosted implementation.\n- Uploaded-file and generated-file transfer require separate host integration checks. A supported schema alone does not prove a particular host exposes either file.\n",
|
|
1144
|
+
"revision": "c2262fc4f30e9898"
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
"id": "local",
|
|
1148
|
+
"title": "Build locally and send to Sprid",
|
|
1149
|
+
"summary": "Build content with your own tools, upload originals into Sprid, and continue editing, reviewing and measuring the same posts in chat or the dashboard.",
|
|
1150
|
+
"url": "https://sprid.studio/docs/local",
|
|
1151
|
+
"markdown": "# Build locally and send to Sprid\n\n**What this guide does:** Build content with your own tools, upload originals into Sprid, and continue editing, reviewing and measuring the same posts in chat or the dashboard.\n\nRead [one marketing plan](../../../references/guided-marketing.md). Preserve the shared action and artifact identity when moving local output into Sprid; login failure must leave the local result usable.\n\n## Name the work\n\n`sprid media` owns local production and file transfer. `sprid post` owns shared server posts. Sprid MCP reaches the same connected operations from chat; optional Sprid skills teach the method. A plugin packages the skills and MCP configuration.\n\n`sprid media` is the prefix for that local pipeline: `build`, `register`, `check`, `push` and `preview`. A numeric local slug stays local: shared preview is explicitly `sprid post preview --id <postId>`.\n\n## Build and upload\n\nUse your app's existing renderer or design tools. `sprid media init` configures built-in stills or simulator-screen recipes; `sprid media build <slug>` builds through that configuration. `sprid media check <slug>` checks the output. Trusted TS/JS configuration executes local code. Native captures and binary builds require the app's own environment.\n\nSign in with `sprid login`. For finished files, run:\n\n```sh\nsprid media upload slide-01.png slide-02.png --account my-account --json\n```\n\nThe upload goes directly to storage. Sprid checks the original bytes and returns ordered asset IDs. PNG, JPEG, WebP and MP4 imports are bounded at 32 MiB per file; the existing local `push` video path handles larger files under its own limits. The command prints its request ID before uploading. Resume with the same files in the same order and `--request-id <UUID>`; read saved results with `sprid media job <UUID>`. Do not reuse a session for a different ordered selection.\n\nCreate `draft.json` with the returned IDs:\n\n```json\n{\n \"account\": \"my-account\",\n \"requestId\": \"5e253644-d8a5-4b18-9cc9-d4d921874138\",\n \"title\": \"A concrete moment\",\n \"captionInstagram\": \"The caption, with hashtags at the end\",\n \"aspectRatio\": \"4:5\",\n \"presentation\": \"finished\",\n \"assets\": [{ \"kind\": \"image\", \"id\": 101 }, { \"kind\": \"image\", \"id\": 102 }]\n}\n```\n\nReplace the example request ID with a new UUID for each new draft, then keep it for retries. Use `kind: \"video\"` and one asset for a finished reel. Finished artwork gets no new overlay or music. Images fit inside the selected canvas; inspect any margins in the shared preview.\n\n```sh\nsprid post create --file draft.json --json\nsprid post get 123 --json\nsprid post update 123 --file changes.json --json\nsprid post preview --id 123 --json\nsprid post deliveries 123 --json\n```\n\n`changes.json` uses the existing post-update schema, for example `{\"captionInstagram\":\"Revised caption\"}`. Continue in chat by supplying post ID `123`; do not create another draft. The returned review link opens the same dashboard screen used from MCP. Human approval and platform choices remain explicit. Read delivery receipts before reporting success.\n\n## Hosted options and results\n\n`sprid capabilities --json` reports server limits and local-only tasks. `sprid media import --file sources.json` accepts the same account/files/urls/assets payload as MCP `import_assets`. `sprid media reel --file recipe.json` starts the explicit metered hosted recipe; the payload and approval requirements are in `sprid docs chat`. Poll with `sprid media job <UUID>`.\n\nUse `sprid marketing-review` for connected evidence, and the optional marketing-review skill to interpret it alongside repo changes. Secrets are handled by CLI key-file commands or secure Sprid forms, never conversations. Read `sprid docs marketing-review` for coverage and attribution rules.\n",
|
|
1152
|
+
"revision": "426b71b33a6bec2d"
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
"id": "marketing-review",
|
|
1156
|
+
"title": "Review marketing from connected evidence",
|
|
1157
|
+
"summary": "Investigate acquisition, activation, retention and revenue through Sprid-held connections, with an explicit account of missing evidence when no repository is available.",
|
|
1158
|
+
"url": "https://sprid.studio/docs/marketing-review",
|
|
1159
|
+
"markdown": "# Review marketing from connected evidence\n\n**What this guide does:** Investigate acquisition, activation, retention and revenue through Sprid-held connections, with an explicit account of missing evidence when no repository is available.\n\n## Start with the decision\n\nName the app, date range and question. Use `list_apps` and `list_app_profiles` to resolve identity. Read `get_marketing_review_context` for shared definitions, required investigations, prior decisions and corrections. Read `get_marketing_review` for the selected app and two comparable periods. Its default summary links to `view: \"full\", sources: [<source>]` evidence; omit `sources` to include social history, store reviews and milestones. Exact-window snapshots retain collection time. Read the exact saved packet through `get_marketing_review_evidence` with its `evidence.id`, or `sprid marketing-review evidence --id <id> --app <slug>`, even after a connection changes. `refresh: true` requests live reads; `cachedOnly: true` reads stored evidence only. Daily collection covers configured services on active plans, without model calls, publishing or paid social reads. Pause through the App Profile's `metricsCollectionEnabled: false` or `sprid marketing-review collection --enabled false`. Stored evidence remains readable. A configuration check does not verify provider access. Preserve returned errors, coverage, population definitions and sample counts.\n\nIn a browser chat, ask for a release summary or public changelog when the question concerns a shipped change. Label it supplied evidence. Do not claim to have inspected a repository or private app database. Local users can add repo diffs and measured database reads through their own authorized tools.\n\n## Follow the evidence\n\nUse `list_marketing_queries` to discover supported operations and their schemas; `query_marketing_source` executes those reads through Sprid-held credentials. Follow pagination and keep truncation visible. Read `get_documentation` with `topic: \"metrics\"` for definitions and refused calculations, and `topic: \"queries\"` for source-specific queries.\n\nSeparate acquisition from activation and people from events. Compare equal date windows and comparable populations. A post impression is not an app install; a download is not an activated user. Missing onboarding events require an instrumentation recommendation, not a guessed funnel. Keep revenue rails separate until the overlap check supports adding them.\n\nFor each finding, test an alternative explanation: changed tracking, traffic exclusions, attribution window, seasonality or a different audience mix. Observational before/after changes do not establish causality. If a difference is within normal variation or the sample is too small, say so and avoid ranking it as a result.\n\n## Keep the review portable\n\nSave selected non-secret definitions, investigations, decisions, corrections and release references through `save_marketing_review_context` when sharing context is authorized. Send `baseRevision` from the latest read. A conflict returns both proposals; reconcile before retrying. Stored context is an assertion with references, not independent verification. CLI parity: `marketing-review context --app <slug>` reads, `--file <context.json>` imports `{baseRevision,context}`. Keep local private notes local.\n\nUse `add_event` for confirmed product or marketing changes with the relevant areas and why. Save a completed review as an app-scoped `kind: \"note\"` event: label the review date and keep its conclusion, evidence references, coverage and next hypothesis in `meta`. Retrieve it through `list_events` in another client. `log_reflection` is specifically for a post's supplied performance statistics. Store no secrets or signed attachment URLs in either record.\n\nReport the decision first, then the evidence, limitations and the observation that would change it. Keep failed provider reads separate from successful empty data. Read `next_actions` for the relevant shared follow-up. A missing credential goes to the secure App Profile form or CLI key-file command; no provider MCP installation is required for a supported Sprid query.\n\n## Collection and coverage\n\nThe scheduler refreshes two rolling 30-day windows daily and re-reads late provider exports. Snapshots are private, app-scoped, configuration-bound and retained for 90 days; local evidence exports remain the durable report archive. Other windows are collected on demand. Missing days stay unknown, and incomplete store/GSC windows withhold percentage changes. Daily unique people must never be summed into a monthly population. Snapshot collection does not make unequal cohorts comparable or establish that a product change caused an outcome.\n\nA `configuration_only` result proves saved identifiers and key presence, not access. Diagnostics return a safe code, HTTP status when known, retryability and an operation-specific next step. Retry transient errors before recommending reconnection. Unsupported metrics and provider privacy thresholds remain explicit investigation limits.\n",
|
|
1160
|
+
"revision": "9894c112e82dc295"
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
"id": "traffic",
|
|
1164
|
+
"title": "Check whether a traffic spike is real",
|
|
1165
|
+
"summary": "Tells you how to judge a sudden jump in website visitors, and how to remove a scraper from your numbers without removing customers. Read it before you act on a spike, and before you explain one.",
|
|
1166
|
+
"url": "https://sprid.studio/docs/traffic",
|
|
1167
|
+
"markdown": "# Check whether a traffic spike is real\n\n**What this guide does:** Tells you how to judge a sudden jump in website\nvisitors, and how to remove a scraper from your numbers without removing\ncustomers. Read it before you act on a spike, and before you explain one.\n\nA spike is not evidence of a bot, and a quiet baseline is not evidence of\npeople. Both mistakes cost the same: one makes you chase a channel that never\nexisted, the other makes you drop real readers from your own scoreboard. Decide\nwith the four reads below, in order, and keep the rule you save as narrow as the\nevidence you actually have.\n\nSprid raises this for you. When one day carries at least 35% of a 30-day\nperiod and runs at ten times the median day, `next` shows **Review that day**\nwith the date, the multiple and that day's pageviews per visitor beside the\nrest of the month. It is a prompt, not a verdict: nothing in a daily series\nseparates a crawl from a day that went well, which is what the rest of this\nguide is for.\n\n## Four reads, in order\n\n**1. Find the hours, not the day.** Get daily visitors for the period, then\nsplit the suspect day by hour. Marketing arrives across a day and decays over\nseveral. A scrape is a block: it starts, runs at a flat rate for a few hours and\nstops. If the day's total lands in four consecutive hours and the hours either\nside are ordinary, you are looking at one client, not an audience.\n\n**2. Divide pageviews by visitors, and do not trust it on its own.** A browser\nthat keeps no cookie is a new person on every request, so a crawl that reads\neach page once reports a huge visitor count at 1.0 pageviews each, and that is\nworth seeing. But a crawler that hits each URL several times does not look like\nthat at all: the September 2026 scrape ran at **1.60 pageviews a visitor\nagainst a baseline of 1.44** — higher than the real traffic it was hiding in.\nRead the number, let a flat 1.0 accuse, and never let a healthy-looking ratio\nacquit.\n\n**3. Ask for the compound group, never the dimensions separately.** `review_traffic`\nreturns whole groups — browser, version, OS, screen, timezone, referrer,\ncountry together — because adding up independent dimension counts double-counts\neveryone. One group carrying most of a day is the finding. Twelve groups sharing\nit evenly is not, unless they agree on something (see below).\n\n**4. Look at which pages were hit.** A crawl walks your sitemap: every locale,\nevery item, a handful of hits each, nothing concentrated. Real discovery is\nlopsided — a few pages take most of the traffic, and they are the pages that\nrank or were linked.\n\n## What the fingerprint actually looks like\n\nSort the fields by how hard they are to fake, and read the hard ones:\n\n- **Timezone against geography** is the strongest single tell. A browser\n reporting `Asia/Shanghai` while the IP geolocates across the United States,\n Singapore and Germany is one operator on rotating addresses. The address is\n rented; the container's clock is not.\n- **An odd viewport** — `800x600`, `1512x982`, `1280x720` — beats the user\n agent, because the user agent is the field they bother to spoof. Expect a\n plausible current Chrome on macOS with a screen no customer has.\n- **A blend is itself a signature.** One wave rotated across Chrome 118–120,\n Edge 119–120 and Firefox 120–121 so that no browser stood out — on one\n viewport, one timezone and one referrer. What they varied is noise. What they\n forgot to vary is the rule.\n- **Referrer `$direct`** on everything, with no search or social mixed in.\n- **Country is not the tell.** The same wave arrives from a dozen of them. A\n country rule removes customers and keeps the scraper.\n\n## The trap: your comparison period is contaminated too\n\nA percentage has two numbers in it, and the older one is the one nobody looks\nat. On one app in September 2026 the same thirty days read **+252.5%** before\nany review, **-62.6%** with only the obvious spike day excluded, and **-17.6%**\nonce two earlier waves in the comparison period were excluded as well. Same\ndata, three answers, two of them wrong, and the middle one was the most\nconvincing because it was already a correction.\n\nSo when you find one wave, look for its siblings before you save anything.\nQuery the whole visible history for the marker you just identified — the\ntimezone, the viewport — and read it by day. Waves have edges: a background of\n5 to 30 visitors a day with several hundred on the wave days tells you both\nwhere the rule starts and that the rest is ordinary.\n\n## Two more things that will catch you out\n\n**Raw provider data is not what Sprid counted.** Web visitors already exclude\nevents with no browser, crawler and headless user agents, reported bots, and\nanything marked internal or test. A wave that arrives with a null browser never\nreached your total, so a raw query that includes it will not reconcile with the\ncard. Compare like for like or you will exclude the same traffic twice.\n\n**Bound a rule as tightly as its conditions are ordinary.** `1920x1080` is a\nreal screen that real customers use, so a rule built on it gets the wave's dates\nand nothing wider. A viewport nobody has can carry a longer window. The date\nrange is the safety margin for a condition that is not distinctive on its own.\n\n## Saving the exclusion\n\nReview the range, preview the effect, then save. `review_traffic` previews\nvisitor counts before and after for the period **and the one before it**, which\nis the number you want to see move.\n\n```json\n{\n \"id\": \"scrape-2026-09-18\",\n \"reason\": \"Full-site crawl 04:00-08:00 UTC: Asia/Shanghai timezone, 800x600 viewport, direct referrer, IPs across US/SG/DE. 39,958 of the day's 40,476 visitors, every locale and item page hit at most 5 times with no cookie reuse.\",\n \"start\": \"2026-09-18\",\n \"end\": \"2026-09-19\",\n \"enabled\": true,\n \"conditions\": [\n { \"field\": \"timezone\", \"value\": \"Asia/Shanghai\" },\n { \"field\": \"screenWidth\", \"value\": \"800\" },\n { \"field\": \"screenHeight\", \"value\": \"600\" }\n ]\n}\n```\n\nEnd dates are exclusive and UTC. Conditions inside a rule are AND; separate\nrules are OR. Fields: `browser`, `browserVersion`, `os`, `osVersion`,\n`screenWidth`, `screenHeight`, `timezone`, `referrer`, `country`. Values are\nexact strings and a missing property never matches. Write the `reason` for\nsomeone who finds the rule in a year and has to decide whether it still holds —\nname the window, the evidence and the size of what it removes.\n\nSave it through `upsert_app_profile` or `PATCH /api/app-profiles/:id` under\n`posthogConfig.trafficExclusions`, preserving the rest of the configuration. Then\n**log the change as an event** with the areas it can explain and why, or the drop\nin your own graph becomes a second mystery a month from now.\n\n## What it does not touch\n\nYour provider's stored data is never changed or deleted; the exclusion is a\nfilter Sprid applies when it reads. Native app activity, registrations and\nrevenue are unaffected — a scraper does not sign up. Raw connected queries and\nthe marketing-review event inventory stay unfiltered on purpose, because they\nare the evidence you check the rule against. **Restore this traffic** disables a\nrule and the original numbers come straight back.\n\n## When not to exclude\n\nA spike with a real referrer and a lopsided page distribution is a link that\nworked. Find it before you filter it. A shared\noffice machine, an uptime probe and a preview renderer all produce a repeated\nfingerprint and none of them is worth a rule. And a group you cannot explain\nstays in the numbers: an unexplained visitor counted is a smaller error than a\ncustomer removed.\n",
|
|
1168
|
+
"revision": "4b12201d75a57af1"
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
"id": "pinterest-content",
|
|
1172
|
+
"title": "Pinterest content and publishing",
|
|
1173
|
+
"summary": "Plan searchable Pins, approve a useful batch, let Sprid publish the selected Pins on schedule and judge the result by qualified traffic and activation.",
|
|
1174
|
+
"url": "https://sprid.studio/docs/pinterest",
|
|
1175
|
+
"markdown": "# Pinterest content and publishing\n\n**What this guide does:** Plan searchable Pins, approve a useful batch, let Sprid publish the selected Pins on schedule and judge the result by qualified traffic and activation.\n\nChecked against Pinterest’s current guidance on 21 September 2026. Recommendations labelled as tests are starting hypotheses, not claims about what will win for your account.\n\n## How Pinterest discovery works\n\nPinterest works as a visual search and recommendation system. A Pin can appear in search, home feeds and related recommendations long after publication. Discovery does not depend primarily on followers.\n\nPinterest says relevance comes from signals in the Pin and how people interact with it. Clear keywords, original imagery, link quality and relevant board context help Pinterest understand the subject; Pinterest does not publish a fixed weighting for them. Give one coherent answer to “what is this about?” across the visual, title, description, board and landing page. Use the language a person would search, without repeating a keyword unnaturally.\n\nPins can remain discoverable after publication. Compare results at equal Pin ages, and keep older useful Pins in the analysis instead of treating the first day as the full result.\n\n## Start with the destination\n\nChoose the page and desired user action before making the visual:\n\n1. Pick one useful guide, tool, feature page or store destination.\n2. State the concrete question it answers.\n3. Choose one action that continues the same task, such as opening the relevant feature or starting its setup.\n4. Add campaign parameters without deleting existing URL parameters. Use a stable Pin or creative identifier so visits can be traced back to the exact Pin.\n\nThe destination must deliver the pictured promise immediately and work well on a phone. A specific Pin leading to a generic homepage usually breaks that promise. A store visit is not an install, and an outbound click is not activation; keep each step separate in reporting.\n\n## Choose topics and boards\n\nUse Pinterest Trends, Pinterest search suggestions, customer language and proven site queries to build a topic list. Search Console is a useful seed, but Google demand does not prove Pinterest demand.\n\nMix evergreen questions with relevant seasonal moments. Use a focused board whose name and description explain the topic. A Pin about apartment-viewing costs belongs on a board about buying an apartment, not a broad “Ideas” board. Create a new board only when the topic will support a useful collection.\n\n## Choose a cadence to test\n\nSprid recommends **2 original Pins per day as an initial experiment**, spread across separate slots. With a broad catalog of useful destinations and genuinely distinct assets, test **5 per day** against that baseline. These are proposed test settings, not Pinterest limits or proven optima. A limited destination library calls for expanding useful content, not filling the queue with cosmetic duplicates.\n\nCreate and review batches together, then spread publication across the calendar. Rotate destination pages and topics. Start with two distinct creative treatments per destination; space those treatments across different days. Neither an exact spacing interval nor a universal best hour is established by the evidence reviewed.\n\nPinterest itself recommends original content at least weekly. Marketer examples range from one daily Pin to several: [Sarah Hanford](https://www.sarahhanford.com/blog/pinterest-growth-organically-60-days) reports moving from three daily to five, alongside keyword research and a new website. That does not isolate frequency as the cause of growth.\n\n[Tailwind’s benchmark](https://www.tailwindapp.com/pinterest-marketing/research/2025-benchmark-study-part-1) covered approximately 1.2 million organic Pins, using 2024 data. Results were concentrated in a small share of Pins. Its English-speaking customer sample and observational design cannot establish a universal cadence or predict another market’s conversions.\n\nReview cohorts at 30, 60 and 90 days of Pin age. Change one variable per test and repeat across comparable destinations. Keep higher frequency when additional Pins repeatedly produce additional qualified visits or activations; a lower click rate alone does not invalidate growth in total qualified traffic. Report counts and coverage, including results with the leading Pin removed, so one outlier cannot determine the strategy.\n\n## Build the Pin\n\nFor an image Pin, use **2:3**, ideally **1000 × 1500 px**. For full-screen video, use **9:16**, ideally **1080 × 1920 px**. Pinterest currently allows organic video from **4 seconds to 5 minutes** with H.264 or H.265 encoding.\n\nSprid publishes one selected image or one finished video per Pin. It does not silently turn a multi-slide Instagram carousel into a Pinterest Pin. Prepare a dedicated Pinterest asset and inspect its crop in the preview.\n\nAt feed-thumbnail size, the subject and benefit should still be clear. Use one visual focus, strong contrast and brief readable overlay copy. Check the real phone preview. The Pin must stand alone; an Instagram opener that only makes sense after swiping to slide two is incomplete here.\n\nUseful formats to test include:\n\n- an editorial cover for a specific guide;\n- a reference card with a concrete checklist or answer;\n- a real product or app demonstration showing one task;\n- a coherent visual collection for design, travel or architecture;\n- a short captioned video when motion explains the task better than a still.\n\nPinterest can label detected or declared AI imagery. Preserve provenance, use accurate licensed assets and make any required disclosure. Never publish an image that misrepresents the linked place, product or result.\n\n## Write the metadata\n\nOrganic Pin titles allow **100 characters**. Put the useful subject early because only part of the title may appear in a feed. Descriptions allow **800 characters**. Descriptions may be hidden in home and search feeds, but Pinterest uses them to understand relevance.\n\nAlt text allows **500 characters** in the Pinterest API. Describe what the visual shows for someone who cannot see it; do not use alt text as another keyword field. Choose an AI disclosure in Sprid when it applies to the asset.\n\nWrite a natural title and description that name the topic, audience or situation and what the destination provides. Choose a relevant board and add a working destination. Do not stuff variants of the same keyword, use unrelated trends or promise something the page does not deliver.\n\nThe visual earns attention; metadata supplies context; the destination completes the task. Keep all three aligned.\n\n## Publish your first Pin\n\nPublishing and scheduling require Sprid’s Pinterest app to have Standard access. With Trial access, you can connect the account, browse boards and prepare drafts, but Sprid will refuse the publish or schedule request. This access tier belongs to Sprid’s integration; the customer does not apply for a developer app.\n\n1. Connect Pinterest, then run `sprid status` and confirm the intended account.\n2. Create or open a post with exactly one image, preferably at 2:3, or one finished video, preferably at 9:16.\n3. Open **Publish**, select **Pinterest**, then choose a **Board** and optional section.\n4. Add the Pin title, description, destination, alt text and any AI disclosure.\n5. Inspect the rendered creative and every public field. Publish now or choose a future time.\n6. After delivery, open the Pin while signed out or from another account and follow its destination.\n\nIn the CLI, use `sprid pinterest boards --account <slug>` to find board IDs. If there are none, it says so; create one with `sprid pinterest create --account <slug> --name <name> [--privacy public|secret]`. Then use `sprid pinterest set <postId> --board <id> --link <url>` with the optional metadata flags shown by `sprid docs cli`. The command saves the draft; review and schedule it in Sprid. Later, `sprid pinterest metrics <publishId> --account <slug>` reads a bounded results window.\n\nWith MCP, read `get_documentation` topic `pinterest-content`, select the exact channel from `list_connections`, then call `list_pinterest_boards`. If it returns no boards, say so and call `create_pinterest_board` only with a user-approved name and privacy. Save `pinterestOptions` with `update_post`. Prefer `aspectRatio: \"2:3\"` for a new image Pin. Render the preview, show the user the specific Pin or dry-run batch, then call `schedule_post` or commit `schedule_batch` only for the Pins they selected. Use `get_pinterest_metrics` for results.\n\n## Review and schedule in Sprid\n\nFor a two-Pin daily test, choose **Daily** and two separate times in the batch scheduler. For example, **09:00 and 17:00** are convenient slots, not researched best posting times. Check the returned account timezone and the actual dates before confirming; do not assume they match your device. Keep an existing user-chosen cadence unless they ask to change it.\n\nOrder the selected Pins so different destinations alternate. Review the calendar preview for occupied days, gaps and any unplaced Pins. A large batch is fine to prepare at once; its publication can be spread across the schedule.\n\nFor MCP, use `schedule_batch` with `cadence: \"daily\"`, `times: [\"09:00\", \"17:00\"]`, the chosen account/channel and selected post IDs. Start with `dryRun: true`, then inspect `placements`, `unplaced` and `timezone`. Busy days are skipped by default, so check the returned plan rather than promising a fixed completion date. Commit only the reviewed selections and report what was actually booked. CLI users can read this guide with `sprid docs pinterest-content` and review the queue with `sprid queue`; use the scheduling UI or connected MCP tools to place the batch.\n\nA time-only move keeps the reviewed creative and destination. If you change a scheduled Pin’s content, board or link, review and reschedule the updated Pin. Changed drafts can be blocked at publication until reviewed again. After an ambiguous publishing failure, check Pinterest before retrying because the original Pin may already exist.\n\nReview every selected Pin’s rendered creative, public metadata, destination, board and scheduled time. Check factual claims, rights and disclosure before approving the batch.\n\nPinterest’s published developer guidelines require the user to choose each Pin that will be published. Sprid implements that rule by showing the concrete Pins and their schedule, then recording the user’s batch selection. Those selected Pins publish automatically at their scheduled times; the user does not return to approve the same unchanged schedule again. Review any new or edited Pin before adding it to a schedule.\n\nAfter the first scheduled Pin publishes, verify its public visibility and destination from outside the connected Pinterest account. A draft, preview or accepted schedule is not proof of delivery.\n\n## Measure what happened\n\nKeep Pinterest’s metrics distinct:\n\n- **Impressions:** times the Pin was on screen.\n- **Saves:** times people saved it to a board.\n- **Pin clicks:** clicks that opened the Pin in close-up.\n- **Outbound clicks:** actions leading to a destination outside Pinterest.\n- **Video views:** at least 2 seconds with at least 50% of the video in view.\n\nFor app growth, the useful path is **impression → outbound click → qualified landing visit → app action → activation**. Use saves as a diagnostic, not the final success metric. A Pin with many saves and few outbound clicks may be valuable as an on-platform reference while contributing little acquisition.\n\nCompare Pins of similar age within the same topic, language and market. Judge creative using outbound-click rate and qualified visits; judge the whole path using activations per Pin and, where available, revenue. Pinterest-reported outbound clicks and first-party website sessions use different measurement methods, so show both rather than forcing them to match.\n\nIf visits arrive but activation does not, inspect page speed, message match and the next app action before making more Pins. If impressions are low, inspect topic relevance, board context, metadata and visual clarity. If qualified traffic and activation remain negligible across repeated relevant cohorts, stop scaling that app’s Pinterest output.\n\n## Improve the next batch\n\nChange one meaningful element within a comparison: visual treatment, question, format or destination angle. Organic distribution is not randomized, so call the result a directional test, not a controlled A/B experiment.\n\nCreate fresh, useful treatments rather than cosmetic duplicates. [Tailwind’s freshness study](https://www.tailwindapp.com/pinterest-marketing/research/2025-benchmark-study-part-three) found stronger retained distribution from new images for an existing URL than from repeatedly reusing the same image and URL; this is association, not a guaranteed lift. Pinterest advises against repeatedly uploading the same Pin, and repetitive or irrelevant commercial content can be treated as spam. Spread treatments of the same destination apart and keep every Pin on a relevant board.\n\nUse the next review to choose topics and destinations for another test. For example, [Elaine Timms’s recipe-client case](https://elainetimms.com/evergreen-growth-how-food-creator-pins-for-profit/) combines search-specific overlays, creative variants and email opt-ins. Adopt the connected workflow; its reported growth cannot be attributed to cadence alone.\n\n## Prepare the website\n\nClaim an owned website in Pinterest to associate the profile with Pins from that domain and expand website analytics. One website can be claimed by only one Pinterest account.\n\nFor eligible articles, products or recipes, add the relevant Open Graph or Schema.org metadata for Rich Pins. Rich Pins synchronize information from the page; they are website metadata, not a separate Sprid export. Check how that metadata appears before publishing a batch because a manual Pin edit can override synced article or recipe information.\n\nMake sure Pinterestbot can read the destination, links work and pages load quickly on mobile. Preserve any existing URL parameters when adding attribution.\n\n## Sources\n\n- [How Pinterest discovery works](https://create.pinterest.com/blog/how-to-increase-discoverability-seo-pinterest/)\n- [Growing through search, boards and keywords](https://create.pinterest.com/blog/best-ways-to-grow-on-pinterest/)\n- [Pin specifications](https://help.pinterest.com/en/article/review-pin-specs)\n- [Pin performance and distribution](https://help.pinterest.com/en/business/article/pin-performance-and-distribution)\n- [Pinterest Analytics definitions](https://help.pinterest.com/en/business/article/pinterest-analytics)\n- [Pinterest developer guidelines](https://policy.pinterest.com/en/developer-guidelines)\n- [Pinterest API schema](https://github.com/pinterest/api-description/blob/main/v5/openapi.json)\n- [Pinterest community guidelines](https://policy.pinterest.com/en/community-guidelines)\n- [Pinterest labels for AI-generated or modified images](https://help.pinterest.com/en/article/gen-ai-labels)\n- [Claim your website](https://help.pinterest.com/en/business/article/claim-your-website)\n- [Rich Pins](https://help.pinterest.com/en-gb/business/article/rich-pins)\n",
|
|
1176
|
+
"revision": "2426b956266bf702"
|
|
1177
|
+
}
|
|
1178
|
+
];
|