Skip to main content
RapidDev - Software Development Agency
replit-integrationsStandard API Integration

How to Integrate Replit with Sprout Social

To integrate Replit with Sprout Social, create an API application in the Sprout Social developer portal to get OAuth 2.0 credentials, store them in Replit Secrets (lock icon πŸ”’), and call the Sprout Social API v1 from your Python or Node.js server to publish content, retrieve engagement data, and pull social analytics reports. Use Autoscale deployment for publishing automation workflows.

What you'll learn

  • How to register a Sprout Social API application and obtain an access token
  • How to store Sprout Social credentials securely in Replit Secrets
  • How to retrieve customer profiles and engagement data using Python and Node.js
  • How to publish and schedule social media posts via the Sprout Social API
  • How to pull cross-channel analytics reports from the Sprout Social reporting API
Book a free consultation
4.9Clutch rating ⭐
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read35 minutesMarketingMarch 2026RapidDev Engineering Team
TL;DR

To integrate Replit with Sprout Social, create an API application in the Sprout Social developer portal to get OAuth 2.0 credentials, store them in Replit Secrets (lock icon πŸ”’), and call the Sprout Social API v1 from your Python or Node.js server to publish content, retrieve engagement data, and pull social analytics reports. Use Autoscale deployment for publishing automation workflows.

Why Connect Replit to Sprout Social?

Sprout Social sits at the intersection of social publishing, engagement management, and analytics β€” making it the preferred platform for marketing teams that need all three in one place. Its API exposes the core capabilities: managing profiles across Twitter, Facebook, Instagram, LinkedIn, and Pinterest, publishing and scheduling posts, retrieving incoming messages for engagement workflows, and pulling detailed analytics including post performance, audience growth, and competitor benchmarking.

Connecting your Replit app to Sprout Social enables integration patterns that the native Sprout interface does not support: triggering post creation from product events, pulling social analytics into a custom data warehouse, routing incoming messages to your CRM for customer service follow-up, and building custom reporting dashboards tailored to your specific KPIs. These are the use cases that enterprise social teams pay for in expensive third-party integrations, which you can build directly with the Sprout API.

Replit's Secrets system (lock icon πŸ”’ in the sidebar) keeps your Sprout Social access token encrypted and accessible only to server-side code. The Sprout Social API access token grants full access to your connected social profiles including the ability to post content β€” it must never appear in client-side JavaScript or be shared publicly. Store it in Replit Secrets and access it only from your Replit backend server.

Integration method

Standard API Integration

You connect Replit to Sprout Social by registering an application in the Sprout Social developer portal to get OAuth 2.0 credentials, storing the access token in Replit Secrets, and calling the Sprout Social API v1 from your server-side Python or Node.js code. The Sprout Social API uses Bearer token authentication. The base URL is https://api.sproutsocial.com/v1.

Prerequisites

  • A Replit account with a Python or Node.js project created
  • A Sprout Social account on a plan that includes API access (Professional or Advanced)
  • Access to the Sprout Social developer portal at developer.sproutsocial.com
  • At least one social profile connected to your Sprout Social account
  • Python 3.10+ or Node.js 18+ (both available on Replit by default)

Step-by-step guide

1

Create a Sprout Social App and Get an Access Token

Visit developer.sproutsocial.com and sign in with your Sprout Social account. Navigate to 'My Apps' and click 'Create New Application'. Fill in the app name, description, and website URL. For the callback URL, enter your deployed Replit URL plus a callback path (e.g., https://your-app.replit.app/oauth/callback). After creating the app, Sprout Social provides a Client ID and Client Secret. The OAuth 2.0 flow for Sprout Social uses a standard authorization code flow. You can generate an access token directly from the developer portal for personal or testing use β€” look for the 'Access Token' section on your app's detail page and click 'Generate Token'. This bypasses the full OAuth flow and gives you a long-lived token suitable for server-to-server integrations. Copy the access token. Open your Replit project and click the lock icon πŸ”’ in the left sidebar. Add the following Secrets: - SPROUT_ACCESS_TOKEN: your generated access token - SPROUT_CLIENT_ID: your app client ID (needed for OAuth flows) - SPROUT_CLIENT_SECRET: your app client secret The Sprout Social API base URL is https://api.sproutsocial.com/v1. All requests use Bearer token authentication in the Authorization header.

Pro tip: Sprout Social API access requires the Professional or Advanced plan β€” the Standard plan does not include API access. Check your plan in Sprout Social under Account Settings > Subscription to confirm API access is available.

Expected result: Your Sprout Social access token and credentials are stored in Replit Secrets. A test call to GET /profile returns your connected social profiles.

2

Retrieve Profiles and Analytics Data in Python

The Sprout Social API v1 uses standard Bearer token authentication β€” include your access token in the Authorization header for every request. The base URL is https://api.sproutsocial.com/v1. To identify which profiles and networks you have connected, start with GET /profile which returns all customer profiles linked to your Sprout Social account. Each profile has a customer_profile_id that you use in subsequent API calls. The Analytics API provides post-level and profile-level performance metrics. Profile analytics use GET /metrics/profile/{id}/{metric} where the metric can be impressions, engagements, followers, or other network-specific metrics. The reporting endpoints accept date range parameters and return time series data. The Python code below demonstrates how to list connected profiles, fetch profile-level analytics for a date range, and retrieve the top-performing posts by engagement. The response format is consistent JSON with data and paging objects.

sprout_social_client.py
1import os
2import requests
3from datetime import datetime, timedelta
4from typing import Optional
5
6ACCESS_TOKEN = os.environ["SPROUT_ACCESS_TOKEN"]
7BASE_URL = "https://api.sproutsocial.com/v1"
8
9HEADERS = {
10 "Authorization": f"Bearer {ACCESS_TOKEN}",
11 "Content-Type": "application/json"
12}
13
14def get_profiles() -> list:
15 """Get all customer profiles connected to the Sprout Social account."""
16 response = requests.get(f"{BASE_URL}/profile", headers=HEADERS)
17 response.raise_for_status()
18 data = response.json()
19 return data.get("data", {}).get("customer_profiles", [])
20
21def get_profile_analytics(profile_id: str, metrics: list,
22 start_date: str, end_date: str) -> dict:
23 """
24 Get analytics for a specific profile.
25 metrics: list of metric names (e.g., ['impressions', 'engagements', 'followers_gained'])
26 Dates in YYYY-MM-DD format.
27 """
28 params = {
29 "start": f"{start_date}T00:00:00",
30 "end": f"{end_date}T23:59:59",
31 "fields": ",".join(metrics)
32 }
33 response = requests.get(
34 f"{BASE_URL}/metrics/customer/{profile_id}",
35 params=params,
36 headers=HEADERS
37 )
38 response.raise_for_status()
39 return response.json()
40
41def get_sent_posts(profile_ids: list, limit: int = 20) -> list:
42 """Retrieve recently published posts across specified profiles."""
43 params = {
44 "customer_profile_ids[]": profile_ids,
45 "count": limit,
46 "statuses[]": ["sent"]
47 }
48 response = requests.get(f"{BASE_URL}/message/", params=params, headers=HEADERS)
49 response.raise_for_status()
50 return response.json().get("data", {}).get("messages", [])
51
52def get_inbox_messages(profile_ids: list = None,
53 status: str = "all", limit: int = 25) -> list:
54 """Fetch incoming messages from the Sprout Social inbox."""
55 params = {
56 "count": limit,
57 "status": status # 'new', 'in_progress', 'completed', 'all'
58 }
59 if profile_ids:
60 params["customer_profile_ids[]"] = profile_ids
61
62 response = requests.get(f"{BASE_URL}/inbox/", params=params, headers=HEADERS)
63 response.raise_for_status()
64 return response.json().get("data", {}).get("messages", [])
65
66# Example usage
67if __name__ == "__main__":
68 profiles = get_profiles()
69 print(f"Connected profiles: {len(profiles)}")
70 for profile in profiles:
71 name = profile.get('name_for_display', 'Unknown')
72 network = profile.get('network_type', 'unknown')
73 profile_id = profile.get('customer_profile_id')
74 print(f" {name} ({network}): ID {profile_id}")
75
76 if profiles:
77 end_date = datetime.now().strftime("%Y-%m-%d")
78 start_date = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")
79 profile_id = profiles[0]['customer_profile_id']
80 print(f"\nFetching 7-day analytics for profile {profile_id}...")
81 analytics = get_profile_analytics(
82 profile_id,
83 ['impressions', 'engagements', 'followers_gained'],
84 start_date,
85 end_date
86 )
87 print(f"Analytics: {analytics}")

Pro tip: Sprout Social profile IDs (customer_profile_ids) are long integers. Always fetch them dynamically via GET /profile rather than hardcoding them β€” profile IDs can change if a social account is disconnected and reconnected.

Expected result: Running the script prints all connected social profiles with their network types and IDs, and fetches 7-day analytics for the first profile.

3

Publish and Schedule Posts with Node.js

The Sprout Social API supports creating messages (posts) that can be published immediately or scheduled for a future time. The message creation endpoint is POST /message/ and accepts a payload with the message text, the target profile IDs, and an optional send_time for scheduled posting. Each message must specify the customer_profile_ids (the Sprout Social profile IDs you want to post to), the message text, and an optional image URL for image posts. The API returns the created message with a message_id that you can use to check status or update the post before it is published. The Express server below exposes endpoints for immediate publishing and scheduled posting. It also includes a scheduling helper that converts human-readable times to the ISO 8601 format that Sprout Social expects. Install dependencies with 'npm install express axios' in the Replit shell.

server.js
1const express = require('express');
2const axios = require('axios');
3
4const app = express();
5app.use(express.json());
6
7const ACCESS_TOKEN = process.env.SPROUT_ACCESS_TOKEN;
8const BASE_URL = 'https://api.sproutsocial.com/v1';
9
10const sprout = axios.create({
11 baseURL: BASE_URL,
12 headers: {
13 'Authorization': `Bearer ${ACCESS_TOKEN}`,
14 'Content-Type': 'application/json'
15 }
16});
17
18// Get all connected profiles
19app.get('/profiles', async (req, res) => {
20 try {
21 const { data } = await sprout.get('/profile');
22 const profiles = data.data?.customer_profiles || [];
23 const simplified = profiles.map(p => ({
24 id: p.customer_profile_id,
25 name: p.name_for_display,
26 network: p.network_type
27 }));
28 res.json(simplified);
29 } catch (err) {
30 console.error('Profiles error:', err.response?.data || err.message);
31 res.status(500).json({ error: err.message });
32 }
33});
34
35// Publish a post immediately or scheduled
36app.post('/publish', async (req, res) => {
37 const { profileIds, message, imageUrl, scheduledAt } = req.body;
38 if (!profileIds || !message) {
39 return res.status(400).json({ error: 'profileIds and message are required' });
40 }
41
42 try {
43 const payload = {
44 customer_profile_ids: Array.isArray(profileIds) ? profileIds : [profileIds],
45 message_content: [
46 {
47 type: 'text',
48 text: message
49 }
50 ]
51 };
52
53 if (imageUrl) {
54 payload.message_content.push({
55 type: 'image',
56 url: imageUrl
57 });
58 }
59
60 if (scheduledAt) {
61 // scheduledAt should be ISO 8601: 2025-04-01T14:00:00Z
62 payload.scheduled_send_time = scheduledAt;
63 }
64
65 const { data } = await sprout.post('/message/', payload);
66 const messageId = data.data?.id;
67 res.json({ success: true, messageId, scheduled: !!scheduledAt });
68 } catch (err) {
69 console.error('Publish error:', err.response?.data || err.message);
70 res.status(500).json({ error: err.message, detail: err.response?.data });
71 }
72});
73
74// Get analytics for a profile
75app.get('/analytics/:profileId', async (req, res) => {
76 const { start, end } = req.query;
77 const endDate = end || new Date().toISOString().split('T')[0];
78 const startDate = start || new Date(Date.now() - 7 * 86400000).toISOString().split('T')[0];
79
80 try {
81 const { data } = await sprout.get(
82 `/metrics/customer/${req.params.profileId}`,
83 {
84 params: {
85 start: `${startDate}T00:00:00`,
86 end: `${endDate}T23:59:59`,
87 fields: 'impressions,engagements,followers_gained'
88 }
89 }
90 );
91 res.json(data);
92 } catch (err) {
93 console.error('Analytics error:', err.response?.data || err.message);
94 res.status(500).json({ error: err.message });
95 }
96});
97
98app.get('/health', (req, res) => res.json({ status: 'ok' }));
99
100app.listen(3000, '0.0.0.0', () => {
101 console.log('Sprout Social integration server running on port 3000');
102});

Pro tip: Sprout Social's scheduled_send_time must be in ISO 8601 format with timezone (e.g., '2025-04-01T14:00:00Z'). Publishing immediately requires omitting the scheduled_send_time field entirely β€” do not pass null or an empty string.

Expected result: The server starts and GET /profiles returns your connected social profiles. POST /publish with profileIds and message creates a post in Sprout Social's outbox.

4

Deploy and Set Up Webhook Subscriptions

Sprout Social supports webhook subscriptions that notify your Replit server when specific events occur β€” a new message arrives in the inbox, a post is published, a message is tagged, or a conversation status changes. Webhooks enable real-time integrations without polling the API continuously. To configure webhooks, go to your Sprout Social developer application settings and add a webhook endpoint URL under the 'Webhooks' section. Select the event types you want to receive. Sprout Social sends a POST request to your endpoint with the event data in JSON format. Your endpoint must respond with HTTP 200 within 5 seconds. Deploy your Replit app before registering the webhook URL. Click 'Deploy' and choose Autoscale for publishing automation services, or Reserved VM for a dedicated inbox monitoring service that cannot afford cold-start delays. After deployment, copy the stable replit.app URL and register it as the webhook endpoint in your Sprout Social developer app settings.

webhook_server.py
1from flask import Flask, request, jsonify
2import os
3import hmac
4import hashlib
5
6app = Flask(__name__)
7WEBHOOK_SECRET = os.environ.get("SPROUT_WEBHOOK_SECRET", "")
8
9def verify_sprout_signature(payload: bytes, signature: str) -> bool:
10 """Verify the Sprout Social webhook signature."""
11 if not WEBHOOK_SECRET or not signature:
12 return True # Skip if no secret configured
13 expected = hmac.new(
14 WEBHOOK_SECRET.encode(),
15 payload,
16 hashlib.sha256
17 ).hexdigest()
18 return hmac.compare_digest(f"sha256={expected}", signature)
19
20@app.route('/sprout/webhook', methods=['POST'])
21def sprout_webhook():
22 signature = request.headers.get('X-Sprout-Signature', '')
23 if not verify_sprout_signature(request.data, signature):
24 return jsonify({'error': 'Invalid signature'}), 403
25
26 data = request.get_json(force=True)
27 if not data:
28 return jsonify({'error': 'No data'}), 400
29
30 event_type = data.get('event_type', 'unknown')
31 print(f"Sprout webhook: {event_type}")
32
33 if event_type == 'message.inbound.new':
34 message = data.get('message', {})
35 sender = message.get('sender', {}).get('name', 'Anonymous')
36 network = message.get('network_type', 'unknown')
37 text = message.get('text', '')
38 print(f"New message from {sender} on {network}: {text[:100]}")
39 # Route to CRM, create support ticket, notify team
40
41 elif event_type == 'message.sent':
42 message = data.get('message', {})
43 print(f"Post published: {message.get('id')}")
44
45 return jsonify({'status': 'received'}), 200
46
47@app.route('/health', methods=['GET'])
48def health():
49 return jsonify({'status': 'ok'}), 200
50
51if __name__ == '__main__':
52 app.run(host='0.0.0.0', port=3000)

Pro tip: Sprout Social webhook payloads can be large when they include full message content and user profile data. Log only the fields you need rather than the entire payload to keep your Replit deployment logs readable.

Expected result: Your deployed Replit server receives Sprout Social webhook events and logs the event type. The /health endpoint returns 200 to confirm the server is live.

Common use cases

Content Calendar Automation from Product Events

When your product has a new release, a major customer milestone, or a company announcement, your Replit server creates a draft post in Sprout Social for each connected social network and schedules them for the optimal posting times. Marketing teams review and approve posts in Sprout without manually writing content for each platform.

Replit Prompt

Build a Flask endpoint that receives product announcement data (title, description, image URL) and creates a scheduled post in Sprout Social for Twitter and LinkedIn using the SPROUT_ACCESS_TOKEN from Replit Secrets, scheduled for the next business day at 9 AM.

Copy this prompt to try it in Replit

Social Engagement CRM Integration

A Replit server polls the Sprout Social inbox API for incoming messages and mentions, matches them to existing customer records in your CRM by username or email, and creates support tickets or conversation threads when a new social message arrives. This routes social media customer service through your existing support workflow.

Replit Prompt

Write a Node.js script that fetches unread messages from the Sprout Social inbox, filters for messages with negative sentiment tags, and creates a HubSpot support ticket for each one including the original social message text and customer profile URL.

Copy this prompt to try it in Replit

Weekly Cross-Channel Analytics Report

A Replit Python script runs every Monday morning and pulls the previous week's social analytics from all connected Sprout Social profiles: total impressions, engagement rate, follower growth, and best-performing posts. The script formats the data into a structured report and sends it to a Slack channel or email distribution list.

Replit Prompt

Create a Python script that fetches Sprout Social profile analytics for the past 7 days, calculates total impressions and average engagement rate across all connected networks, and formats the results as a weekly summary report.

Copy this prompt to try it in Replit

Troubleshooting

API returns 401 Unauthorized on all requests

Cause: The Bearer token in the Authorization header is invalid, expired, or was revoked in the Sprout Social developer portal. Tokens generated from the developer portal are long-lived but can be revoked manually.

Solution: Verify the SPROUT_ACCESS_TOKEN in Replit Secrets matches the token shown in your Sprout Social developer app settings. If the token was revoked, generate a new one from the developer portal and update the Secret. Test with a simple GET /profile call first.

typescript
1# Python: quick auth test
2import requests, os
3response = requests.get(
4 'https://api.sproutsocial.com/v1/profile',
5 headers={'Authorization': f"Bearer {os.environ['SPROUT_ACCESS_TOKEN']}"}
6)
7print(response.status_code, response.text[:300])

POST /message/ returns 400 with 'invalid profile IDs'

Cause: The customer_profile_ids in the post payload do not match any profiles connected to the account, or the IDs were hardcoded and the social accounts were disconnected and reconnected (which generates new IDs).

Solution: Always fetch profile IDs dynamically via GET /profile before creating messages. Store them in memory or a database rather than hardcoding them. Profile IDs change when social accounts are disconnected and reconnected.

typescript
1# Python: fetch and use profile IDs dynamically
2profiles = get_profiles()
3profile_ids = [p['customer_profile_id'] for p in profiles]
4print(f"Publishing to profiles: {profile_ids}")

Analytics endpoint returns empty data for recent dates

Cause: Sprout Social analytics typically have a 24-48 hour lag. Data for today or yesterday may not be available yet. Additionally, analytics are only available for dates after the social profiles were connected to Sprout Social.

Solution: Use a date range ending 2 days before today to ensure data availability. For real-time metrics, check if Sprout Social offers a real-time dashboard API β€” historical analytics endpoints always have a lag.

typescript
1from datetime import datetime, timedelta
2# Use data ending 2 days ago for availability
3end_date = (datetime.now() - timedelta(days=2)).strftime('%Y-%m-%d')
4start_date = (datetime.now() - timedelta(days=9)).strftime('%Y-%m-%d')

Webhook is registered but no events are being received

Cause: The webhook URL points to a development Replit session that is not active, or the webhook endpoint is returning non-200 responses that caused Sprout to disable it.

Solution: Deploy your app to get a stable URL and re-register the webhook with the deployed URL. Check your deployment logs for errors that would cause non-200 responses. Sprout Social may disable webhooks after repeated delivery failures.

Best practices

  • Store SPROUT_ACCESS_TOKEN in Replit Secrets (lock icon πŸ”’) β€” this token can publish to all your connected social accounts and must never appear in client-side code.
  • Fetch customer_profile_ids dynamically via GET /profile rather than hardcoding them β€” profile IDs change when social accounts are disconnected and reconnected.
  • Request the minimum set of scopes when creating your Sprout Social app β€” use read-only scopes for analytics-only integrations to reduce risk if the token is compromised.
  • Use scheduled_send_time for non-urgent posts to allow Sprout Social's optimal timing recommendations to take effect β€” do not publish everything immediately.
  • Handle the 24-48 hour analytics lag by using date ranges that end at least 2 days before today for analytics queries.
  • Deploy your Replit app before registering webhook endpoints with Sprout Social β€” stable deployment URLs prevent dead webhook registrations.
  • Return HTTP 200 from your webhook handler within 5 seconds, even if internal processing takes longer β€” use async processing and acknowledge immediately.
  • Use Autoscale deployment for publishing automation and Autoscale or Reserved VM for inbox monitoring, depending on how critical real-time response is for your workflow.

Alternatives

Frequently asked questions

How do I store my Sprout Social access token in Replit?

Click the lock icon πŸ”’ in the left sidebar of your Replit project. Add SPROUT_ACCESS_TOKEN with your access token from the Sprout Social developer portal. Access it in Python with os.environ['SPROUT_ACCESS_TOKEN'] or in Node.js with process.env.SPROUT_ACCESS_TOKEN. Never include this token in client-side JavaScript.

Does Replit work with Sprout Social on the free plan?

No. Sprout Social API access requires the Professional or Advanced plan β€” the Standard plan does not include API access. Check your plan in Sprout Social under Account Settings > Subscription. Replit's free tier supports outbound API calls once you have API access, but always-on deployment for webhooks requires Replit's paid plan.

How do I find my Sprout Social profile IDs?

Call GET https://api.sproutsocial.com/v1/profile with your Bearer token. The response includes all connected social profiles with their customer_profile_id, name, and network type. Use these IDs when publishing posts or fetching analytics β€” do not hardcode them as they can change when social accounts are reconnected.

Can I schedule social media posts via the Sprout Social API from Replit?

Yes. Add a scheduled_send_time field to the POST /message/ payload in ISO 8601 format (e.g., '2025-04-01T14:00:00Z'). The post will appear in Sprout Social's publishing calendar and be sent at the specified time. Omit scheduled_send_time entirely to publish immediately.

How do I receive Sprout Social inbox messages in my Replit app?

Register a webhook endpoint in your Sprout Social developer app settings pointing to your deployed Replit URL. Select 'message.inbound.new' as the event type. Sprout Social will POST to your endpoint when new messages arrive in the inbox. You can also poll GET /inbox/ on a schedule if webhooks are not available on your plan.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation β€” no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.