Moving your organisation’s social presence from Twitter to Bluesky or Threads isn’t as simple as creating a new account and posting. You need domain verification, follower migration strategies, cross-posting automation, and analytics that actually work. The technical complexity can derail your migration if you don’t handle DNS configuration, authentication setup, and analytics workarounds properly. Before implementing, consider reading our strategic considerations for migration to understand the broader implications of platform choices.
This guide walks you through the implementation step-by-step for both platforms. You’ll get decision frameworks for infrastructure choices—self-hosted vs managed services—and specific instructions for domain verification on Bluesky, cross-posting automation for both platforms, and analytics configuration. You’ll need domain registrar access, an Instagram Business account for Threads, and basic DNS knowledge. By the end you’ll have a fully operational organisational presence on your new platform with automated posting and proper traffic attribution.
How do I set up domain verification on Bluesky for my organisation?
Domain verification lets you use your company domain as your Bluesky handle instead of the generic @username.bsky.social format. This means your handle can be @company.com, which looks professional and maintains brand consistency.
The process requires adding a DNS TXT record at your domain registrar that points to your Bluesky DID—your decentralised identifier in the AT Protocol system.
Go to Bluesky Settings → Account → Change Handle and enter your domain. Bluesky will give you a verification TXT record to copy. Log into your domain registrar (Cloudflare, GoDaddy, Route53, whatever you use) and navigate to DNS management. Add a new TXT record with the values Bluesky provided.
The TXT record format: Name: _atproto.company.com, Value: did=did:plc:[your-identifier-string]. Copy it exactly as shown.
For the Name/Host field, use _atproto (Cloudflare, Route53) or _atproto.company.com (GoDaddy, Namecheap)—providers like Cloudflare auto-append the root domain. For Value/Content, paste did=did:plc:[your-unique-identifier-string] exactly as shown in the Bluesky verification screen. Set TTL to 3600 (1 hour) for initial setup.
Propagation typically takes 5-30 minutes, occasionally up to 48 hours. You can verify the status in Bluesky Settings → Account—you’ll see a green tick when it’s successful.
You have a choice between a top-level domain handle (@company.com) or a subdomain (@social.company.com). Top-level is recommended for your primary brand presence. Subdomains work well for regional teams or divisions.
If verification fails, use DNS checking tools like whatsmydns.net or dnschecker.org to verify propagation across global DNS servers. These show you whether the DNS record has propagated. Common errors include quotes around the TXT value when your provider doesn’t require them, or incorrect TTL settings. If verification fails after 48 hours, your DNS record format is probably wrong.
For multi-subdomain configuration—like engineering.company.com and marketing.company.com for different teams—repeat the process with the appropriate subdomain in the Name field. Each subdomain gets its own TXT record pointing to its own DID.
Test DNS resolution from the command line using dig (Mac/Linux) or nslookup (Windows) before attempting Bluesky verification to see what the DNS system returns.
The domain verification process leverages domain authority for verification, and your old .bsky.social username stays permanently reserved to your account even after you switch to domain-based verification.
What are app passwords for Bluesky and how do I use them for automation?
App passwords are secondary credentials for programmatic Bluesky access. They’re distinct from your main account password and simpler than OAuth tokens.
Generate one via Bluesky Settings → Privacy and Security → App Passwords → Add App Password. Name it descriptively like “Buffer Integration” or “Cross-posting Tool” so you remember what it’s for. Each app password is shown once during creation, so store it securely in your password manager immediately.
Use app passwords with automation tools like Buffer or Ayrshare, or in custom implementations using the @atproto/api library. When you connect Buffer to Bluesky, for example, you’ll paste the app password into Buffer’s authentication screen along with your Bluesky handle.
The security benefit is straightforward—if a third-party tool gets breached, your main password stays protected. Revoke individual app passwords without changing your main password if an integration is compromised or you no longer need it.
Create separate app passwords for each tool or integration for granular access control. This is recommended practice because it limits damage if something goes wrong and makes tracking which service is doing what much easier.
App passwords differ from OAuth tokens—there’s no complicated OAuth flow here. Just generate the password, paste it into your tool, and you’re authenticated. When the tool makes API calls, it uses your handle and app password to create a session and obtain JWT tokens for subsequent requests.
Should my organisation self-host a Bluesky Personal Data Server or use managed services?
Your Personal Data Server (PDS) is where your Bluesky account’s data lives. By default it’s on Bluesky-managed bsky.social infrastructure. You can also self-host. Before making this choice, understanding Personal Data Servers and their role in AT Protocol’s architecture helps clarify the trade-offs.
The decision factors are data sovereignty requirements, custom moderation policies, long-term platform independence, and your team’s technical capability. Approximately 11.7 million accounts use Bluesky-hosted data stores compared to roughly 59,000 on independent servers across 2,200 data stores.
Managed service advantages: zero infrastructure maintenance, included in free Bluesky usage, automatic updates, established reliability. You create an account and start posting. That’s it.
Self-hosting advantages: full data control, custom invite code management for team provisioning, potential future commercial features, and brand independence. You own the entire stack.
Self-hosting requirements include a VPS or cloud server with 2GB RAM minimum, a domain with DNS access, Docker knowledge, and NGINX reverse proxy configuration if you’re running the PDS alongside existing services. Infrastructure costs run approximately $10-30/month for hosting, plus 4-8 hours initial setup and ongoing maintenance burden.
Start with managed Bluesky hosting during migration for most use cases. Evaluate self-hosting after 3-6 months based on platform commitment and actual usage patterns. The design of PDSes within AT Protocol results in low computational requirements, but “low” doesn’t mean “zero effort.” For a deeper analysis of these trade-offs, see our guide on deciding between self-hosted and managed services.
Self-hosting is justified when you’re handling sensitive communications, requiring custom moderation tooling, planning organisational PDS for 50+ employees, or prioritising exit strategy. For everything else, managed hosting removes operational overhead and lets you focus on content and community.
The AT Protocol’s data portability design means you can migrate between PDS instances later without losing followers or content. Start simple, scale when needed.
How do I connect my Bluesky and Threads accounts to Buffer for cross-posting?
Buffer natively supports both Bluesky and Threads in paid plans, giving you a unified posting workflow across platforms. For a deeper understanding of leveraging platform APIs for automation, see our comparison of API capabilities across both platforms.
For Bluesky, navigate to publish.buffer.com → New Channel → Connect next to Bluesky. Open Bluesky in a separate tab and copy your handle (format: @yourname.bsky.social or your verified domain handle). Generate an app password (see the app passwords section above if you haven’t already). Copy the generated password back to Buffer’s authentication box and click Next.
Bluesky connection requires your handle and app password—not your main password.
Threads connection requires an Instagram Business account already linked to Meta Business Suite. Navigate Buffer → Channels → Add Channel → select Threads → follow the Meta authentication flow. Threads won’t work without an Instagram Business account as the underlying platform, so get that sorted first.
Test the connection by scheduling a single post to verify successful authentication and posting capability. Queue management lets you configure separate posting schedules per platform or use a unified queue with platform-specific time optimisation.
Buffer’s interface shows UTM parameter fields during post scheduling, which you’ll need for analytics (covered later). You can customise content per platform by clicking individual channel boxes when creating a post.
Publishing options include Add to Queue for your scheduled slots, Share Now for immediate publication, Share Next to bump scheduled posts, and Schedule Posts for specific timing. Buffer even supports threaded posts, which aren’t available natively on Bluesky yet.
Alternative tools exist—Ayrshare, Hootsuite, custom API integration—but Buffer has the most mature implementation for both platforms as of early 2026.
How do I track website traffic from Bluesky in Google Analytics?
Bluesky doesn’t pass referrer information to websites. This means Bluesky traffic appears as “direct/none” in Google Analytics 4, which is useless for attribution.
The solution: append UTM parameters to all URLs shared in Bluesky posts.
UTM parameter structure looks like this: ?utm_source=bluesky&utm_medium=social&utm_campaign=[campaign-name]
Full example: https://company.com/article?utm_source=bluesky&utm_medium=social&utm_campaign=product-launch
You have three implementation approaches: manual UTM tagging in Buffer or other posting tools, URL shorteners with automatic UTM injection, or link-in-bio tools.
The parameter breakdown is straightforward. utm_source identifies traffic origin (use “bluesky”). utm_medium specifies channel type (use “social”). utm_campaign tracks specific initiatives (name it whatever makes sense for your campaign tracking).
Configure GA4 to properly categorise Bluesky traffic by ensuring UTM parameters are tracked in Admin → Data Streams → select stream → Configure tag settings. Build a custom GA4 report filtering utm_source=bluesky to isolate Bluesky-driven traffic and conversions.
Apply the same UTM structure to Threads and other platforms for comparative analysis. Consistency in naming conventions makes cross-platform reporting actually useful instead of a guessing game.
Use a URL shortener like Bitly or Rebrandly with UTM auto-tagging capabilities if you want to automate the process.
Make sure to verify your setup works rather than assuming it does. Post a link with UTM parameters and check GA4 real-time reports to confirm the parameters appear correctly.
How do I migrate my Twitter followers to Bluesky or Threads?
No automated follower migration tools exist. Platform API limitations and anti-spam protections prevent bulk follower transfers.
Your manual migration approach: announce the migration on Twitter with your new Bluesky or Threads handles. Pin the announcement tweet. Include the handles in your Twitter bio. Run this announcement campaign for 3-4 weeks before you shift primary activity to the new platform.
For Bluesky, community tools like Fedifinder browser extension scan your Twitter followers for Bluesky handles in their bios and enable bulk following. It’s not perfect but it’s better than manually searching for each person.
Threads leverages Instagram integration. Followers who already follow your company Instagram may discover your Threads presence automatically through Instagram’s interface. This is why having an active Instagram Business account matters for Threads migration.
Content bridging helps—cross-post popular Twitter content to new platforms to demonstrate value and encourage follower migration. People follow accounts that post interesting content. Show them you’re posting interesting content on the new platform.
Expectation management: follower migration typically achieves 10-30% conversion rate in first 3 months. This varies by audience engagement levels. Many users employ both platforms strategically—one for exposure, the other for genuine engagement.
Alternative approach: maintain dual presence during a 6-12 month transition period. Gradually shift primary activity to new platforms while keeping Twitter presence alive for stragglers. This prevents losing your audience entirely if migration doesn’t go as planned.
Metrics to track: follower growth rate on new platforms, engagement comparison (likes, replies, reposts), and Twitter follower decline rate. If Twitter followers aren’t declining and new platform followers aren’t growing, your announcement campaign isn’t working.
Posting frequency on new platforms needs to increase to build algorithm momentum. Both Bluesky and Threads use algorithmic feeds that reward consistent posting. If you only post once a week you won’t show up in anyone’s feed.
What are the server requirements for self-hosting a Bluesky Personal Data Server?
To understand why these infrastructure requirements matter, see our article on AT Protocol architecture fundamentals, which explains how Personal Data Servers fit into the broader network.
Minimum specifications: 2GB RAM, 1 CPU core, 20GB SSD storage, 1TB monthly bandwidth. Recommended specifications for growth headroom: 4GB RAM, 2 CPU cores, 40GB SSD storage.
Operating system: Linux, preferably Ubuntu 22.04 LTS. You’ll need Docker and Docker Compose installed. Architectures supported are amd64 and arm64.
Network requirements: public IP address, open ports 80 (HTTP, for TLS certification verification only) and 443 (HTTPS, for all application requests), and websocket connectivity support. Websocket connectivity is mandatory for PDS to interface correctly with the rest of the Bluesky network.
Domain requirements: dedicated subdomain or domain for your PDS (like pds.company.com) with a DNS A record pointing to your server IP. You’ll also need a wildcard DNS record (*.example.com) for new account creation.
NGINX reverse proxy is optional but recommended if you’re running PDS alongside existing web services on a shared server. The PDS only needs control of two paths: /xrpc/ (main API/RPC endpoint) and /.well-known/atproto-did (domain ownership verification).
Hosting provider examples: DigitalOcean Droplet ($12-24/month), AWS Lightsail ($10-20/month), Vultr ($12-24/month), Linode ($10-20/month). Digital Ocean and Vultr are popular choices in the Bluesky self-hosting community.
Download and run the official PDS installer script via SSH. The installer handles most configuration automatically.
Ongoing maintenance includes monthly security updates, Docker image updates, backup configuration, and monitoring setup. Health check your PDS by visiting https://example.com/xrpc/_health in a browser to confirm it’s running properly.
Use the pdsadmin command-line tool to create admin accounts, generate invite codes for team members, and keep your PDS updated.
Scaling considerations: a single PDS supports hundreds of users. Larger deployments may require load balancing, but you won’t hit that scale unless you’re running PDS for 500+ users.
The Caddy web server is included in the Docker compose file and handles TLS automatically via Let’s Encrypt, so you don’t need to set up SSL certificates manually.
How do I implement automated posting to both Bluesky and Threads using custom code?
For Bluesky, use the official @atproto/api JavaScript library or equivalent in Python (atproto) or Go (indigo). For Threads, you’ll need Instagram Business account access via Meta Graph API with Instagram content publishing permissions. Our guide on API integration patterns covers the detailed differences in API design and capabilities across both platforms.
Bluesky authentication: create a session using your handle and app password, which gives you an access token for subsequent API calls. The library handles the authentication flow for you.
Threads authentication uses OAuth 2.0 flow via Meta. You obtain a long-lived access token (60-day expiry) and implement token refresh logic to maintain authentication.
Post creation for Bluesky: initialise BskyAgent, authenticate, call agent.post() with text and optional media attachments. The library includes convenience methods like send_post(), like(), and send_image() with type-hinted models autogenerated from lexicon specifications.
Post creation for Threads: POST request to Instagram Graph API /me/threads endpoint with media URL and caption. Threads API documentation covers single thread posts, carousel posts, threads media, and profiles.
Media handling differs between platforms. Bluesky supports up to 4 images per post via blob upload API—you upload to blob storage first, then create a post referencing the uploaded image. Supported formats are JPEG, PNG, and GIF. Videos support MP4 and MOV formats with 1GB maximum file sizes.
Threads supports single image or video via public URL reference. When cross-posting with identical media, upload to both platforms separately or use a hosting service that provides public URLs for Threads compatibility.
Scheduling implementation uses cron jobs or task schedulers to execute posting scripts at defined times. Store app passwords and OAuth tokens securely—environment variables or secrets management systems, not hardcoded in scripts.
Error handling needs to account for rate limiting, authentication failures, and media processing delays. Implement retry logic with exponential backoff for production deployments. Both platforms apply rate limiting, and hitting limits with no backoff strategy will get your automation blocked.
The AT Protocol uses Personal Data Stores that handle data synchronisation across the network. For most automation needs you won’t interact with these lower-level components directly—the client libraries handle it.
FAQ Section
Can I use my existing Twitter handle as my Bluesky handle?
Bluesky domain verification lets you use your company domain as your handle, providing brand consistency even if your Twitter username differs. You can’t directly transfer @username.bsky.social handles matching Twitter usernames unless that username is available during account creation. Domain verification is the recommended approach for organisations because it maintains recognisable branding independent of username availability.
Does Bluesky support scheduling posts natively?
Bluesky lacks native post scheduling functionality as of January 2026. Use third-party tools like Buffer or Ayrshare for scheduling, or implement custom scheduling using the @atproto/api library with cron jobs. App passwords enable secure third-party tool authentication without exposing main account credentials.
How long does DNS propagation take for Bluesky domain verification?
DNS propagation typically completes within 5-30 minutes but can take up to 48 hours depending on registrar and TTL settings. Use DNS checking tools to monitor propagation status across global DNS servers. If verification fails after 48 hours, verify your TXT record format matches Bluesky’s exact specification without extra quotes or spaces.
Can I migrate my Bluesky account between Personal Data Servers later?
Yes. AT Protocol’s data portability design enables migrating your account, posts, and social graph between PDS instances without losing followers or content. This supports transitioning from managed Bluesky hosting to self-hosted PDS, or between different PDS providers. Migration requires updating your DNS records to point to the new PDS location.
What happens to my Bluesky handle if I let my domain expire?
If your verified domain expires, your Bluesky handle reverts to the default @username.bsky.social format. Your account, posts, and followers remain intact, but your custom domain handle becomes unavailable. Renew the domain and re-verify DNS records to restore your custom handle. Maintain domain registration continuity to prevent handle changes.
Do I need separate Instagram accounts for Threads if I have multiple team members?
Threads requires each user to have an individual Instagram account linked to their personal Threads profile. Organisational posting requires either multiple team members posting from personal accounts or using Buffer or Ayrshare with shared credentials connected to a single Instagram Business account representing your brand.
How do I handle media attachments when cross-posting to Bluesky and Threads?
Bluesky supports up to 4 images per post via blob upload API. Threads supports single image or video via public URL reference. When cross-posting with identical media, upload to both platforms separately or use a hosting service providing public URLs for Threads compatibility. Buffer handles media upload automatically when scheduling to both platforms.
Can I automate replies and mentions monitoring on Bluesky?
Yes. Use the @atproto/api library to fetch notifications via agent.listNotifications(), filter for mentions and replies, and implement automated response logic. Configure webhooks or polling intervals to monitor new notifications. App passwords enable authenticated API access for automation scripts. Rate limiting applies—implement exponential backoff for production deployments.
What analytics limitations should I expect when migrating from Twitter?
Bluesky lacks a native analytics dashboard. Third-party tools provide basic metrics like follower growth and post impressions. No referrer data passes to GA4, requiring UTM parameter workarounds. Threads analytics are available via Instagram Insights when using Instagram Business accounts. Expect less granular data compared to Twitter Analytics, requiring external tracking implementation.
How do I configure NGINX reverse proxy for self-hosted PDS alongside existing services?
Configure an NGINX server block for your PDS subdomain (pds.company.com) with proxy_pass directing to the PDS Docker container port (typically 3000). Enable websocket support with proxy_http_version 1.1 and upgrade headers. Obtain an SSL certificate via Certbot for HTTPS. Only two paths require PDS control: /xrpc/ and /.well-known/atproto-did. Test websocket connectivity using browser developer tools.
What are Bluesky invite codes and do I need them for organisational accounts?
Invite codes were required during Bluesky’s beta phase but are no longer necessary as of February 2024. Anyone can create accounts on bsky.social managed hosting without invitations. Self-hosted PDS administrators can generate invite codes to control team member provisioning on organisational servers, useful for managing account creation permissions.
Can I delete my Twitter account immediately after migrating to Bluesky/Threads?
Not recommended. Maintain Twitter presence for 6-12 months during transition, posting migration announcements and redirecting followers to new platforms. Immediate deletion prevents follower migration and loses your communication channel with audience members not yet on new platforms. Gradual sunset strategy with decreasing Twitter activity and increasing Bluesky/Threads focus enables smoother community transition.