Google Sheets to Instagram and X, posts go out for you
You plan content in a spreadsheet, then lose an hour copying captions, uploading images, and double-checking what already went out. And somehow, a “quick post” turns into a messy game of tabs, logins, and missed drafts.
This is where Sheets social posting hits hardest for marketers managing calendars, but agency owners and social-savvy small business teams feel it too. The outcome is simple: your Google Sheet becomes a reliable queue, and posts publish to Instagram and X on schedule without you babysitting it.
Below you’ll see how the workflow runs, what it automates, and how to set it up so “Pending” rows turn into “Posted” with timestamps.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets to Instagram and X, posts go out for you
flowchart LR
subgraph sg0["Schedule Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:database", form: "rounded", label: "Get row(s) in sheet", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-vertical", form: "rounded", label: "Insta post caption", pos: "b", h: 48 }
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HCTI Image"]
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Post on Twitter"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/facebook.svg' width='40' height='40' /></div><br/>Create Insta post"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/facebook.svg' width='40' height='40' /></div><br/>Post On Instagram"]
n7@{ icon: "mdi:database", form: "rounded", label: "Update Status Posted", pos: "b", h: 48 }
n3 --> n5
n0 --> n1
n5 --> n6
n6 --> n7
n2 --> n3
n1 --> n4
n1 --> n2
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n1,n7 database
class n3,n4,n5,n6 api
classDef customIcon fill:none,stroke:none
class n3,n4,n5,n6 customIcon
The Problem: Social posts live in too many places
Your “content calendar” usually isn’t the problem. It’s the gap between planning and publishing. You might have captions and hashtags in Google Sheets, images in a folder, and approvals in a chat thread. Then posting day arrives and you’re reformatting text for X, building an Instagram image, uploading twice, and hoping you don’t repeat yesterday’s content. Multiply that by a week and you’re spending real time on work that doesn’t improve creative quality at all. Honestly, it’s draining.
It adds up fast. Here’s where it breaks down in the real world.
- Posting to Instagram and X separately invites inconsistency, so the same campaign ends up with mismatched captions and missing hashtags.
- Manual tracking in a spreadsheet is easy to forget, which means content gets reposted or a “Pending” row sits there for days.
- Turning a caption into a clean 1080×1080 image takes longer than it should, especially when you’re doing it one post at a time.
- Access tokens and logins are scattered across tools, so publishing becomes a task only one person can do.
The Solution: Google Sheets becomes your auto-publishing queue
This workflow treats your Google Sheet as the source of truth. Every few hours (default is every 5), n8n checks for rows where Status is marked Pending. For each eligible row, it builds a final Instagram caption by combining your description and hashtags, then creates a simple HTML preview and converts that HTML into a square image using HCTI.io. Once the assets are ready, it publishes a text-only update to X (Twitter) and posts the image plus caption to Instagram via the Facebook Graph API. Finally, it updates the same row in Google Sheets to Posted and adds a timestamp, so you can see exactly what happened without hunting through accounts.
The workflow starts with a schedule trigger. Google Sheets provides the content, HCTI.io generates the post image, and the social publishing happens through API calls (X plus Facebook/Instagram). When the posts succeed, the sheet is updated so your queue stays clean.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you post 10 times a week to Instagram and X. Manually, you might spend about 10 minutes prepping an IG image, 5 minutes cleaning up the caption and hashtags, and another 5 minutes posting to both platforms, which is roughly 20 minutes per post (about 3 hours weekly). With this workflow, you add the row to Google Sheets and set Status to Pending, which takes maybe 2 minutes. The automation runs every 5 hours, generates the image, publishes, and marks it Posted for you.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store posts, status, and timestamps.
- HCTI.io for HTML-to-image generation (1080×1080).
- X (Twitter) OAuth1 credentials (create in the X developer portal).
- Facebook/Instagram Graph API access token (create in Meta for Developers and connect your business IG).
Skill level: Intermediate. You’ll mostly be pasting credentials, updating a Sheet ID/name, and testing one post end-to-end.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A schedule runs it. The workflow starts with a Schedule Trigger (set to every 5 hours by default), so it checks your queue even if nobody is online.
Google Sheets becomes the filter. n8n reads your sheet and pulls the rows where Status equals Pending. That little column is what keeps publishing orderly.
Captions and images are prepared automatically. A “set fields” step composes the final Instagram caption from Desc and Hashtags, then an HTTP request sends HTML to HCTI.io to generate a square image.
Publishing happens, then the sheet is updated. One request posts the text update to X, and two Facebook Graph API steps create and publish the Instagram media. After a successful publish, the workflow updates the row to Posted with a timestamp so you can audit what went out.
You can easily modify the posting interval to fit your calendar. You can also adjust the caption format (for example, rearranging hashtags or adding a CTA) based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Schedule Trigger
This workflow starts on a timed schedule to pull the next pending record and post it to social channels.
- Add and open Scheduled Automation Trigger.
- Set the schedule rule to run every 4 hours (as indicated by the interval rule).
- Connect Scheduled Automation Trigger to Retrieve Sheet Records.
Step 2: Connect Google Sheets
Pull one pending record from Google Sheets and mark it as posted after publishing.
- Open Retrieve Sheet Records and set Document ID to
[YOUR_GOOGLE_SHEET_ID]. - Set Sheet Name to
Sheet1(valuegid=0). - Configure the filter so Status equals
Pendingand enable Return First Match. - Credential Required: Connect your googleSheetsOAuth2Api credentials to Retrieve Sheet Records.
- Open Mark Sheet Posted and set Document ID to
[YOUR_GOOGLE_SHEET_ID]and Operation toupdate. - Map RowID to
{{ $('Retrieve Sheet Records').item.json.RowID }}and Status to{{ 'Posted on ' + $now.toLocaleString() }}. - Credential Required: Mark Sheet Posted does not have credentials configured. Connect your googleSheetsOAuth2Api credentials before running.
Step 3: Set Up Compose IG Caption and Image Generation
This step builds the Instagram caption and renders the HTML image for the post.
- Open Compose IG Caption and set final_caption to
{{ $json["Caption"]+" .................. " +"[" + $json["Desc"] +"]" +" .................. " + $json["Hashtags"] }}. - Set HTML to the provided HTML template value (keep the inline expression
{{ $json.Caption }}inside the template). - Open HTML Image Generator and set URL to
https://hcti.io/v1/imageand Method toPOST. - Set the body parameters: HTML to
{{ $json.HTML }}, viewport_width to1080, and viewport_height to1080. - Credential Required: Connect your httpBasicAuth credentials to HTML Image Generator.
Step 4: Configure Output Actions (Twitter + Instagram)
The workflow posts to X (Twitter) and Instagram. Retrieve Sheet Records outputs to both Publish Tweet Update and Compose IG Caption in parallel.
- Open Publish Tweet Update and set URL to
https://api.x.com/2/tweetsand Method toPOST. - Set the body parameter text to
{{ $json.Caption }}. - Credential Required: Publish Tweet Update requires oAuth1Api credentials but none are configured. Add your X/Twitter OAuth1 credentials.
- Open Create IG Media and set Node to
[YOUR_INSTAGRAM_ACCOUNT_ID]and Edge tomedia. - Set query parameters: image_url to
{{ $json.url }}, caption to{{ $('Compose IG Caption').item.json.final_caption }}, and access_token to[YOUR_FACEBOOK_ACCESS_TOKEN]. - Open Publish IG Media and set Edge to
media_publishwith creation_id as{{ $json.id }}and access_token as[YOUR_FACEBOOK_ACCESS_TOKEN].
Step 5: Test and Activate Your Workflow
Run a manual test to verify the parallel posting, image generation, and status updates.
- Click Execute Workflow and ensure Retrieve Sheet Records finds a row with Status =
Pending. - Confirm Publish Tweet Update posts successfully and HTML Image Generator returns an image URL used by Create IG Media.
- Verify Publish IG Media completes and Mark Sheet Posted updates the sheet with
Posted on …. - Once successful, switch the workflow to Active to enable scheduled runs.
Common Gotchas
- Facebook/Instagram Graph API credentials can expire or need specific permissions. If things break, check your token validity in Meta for Developers and confirm the Instagram business account is linked to the right Facebook Page first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- HCTI.io output depends on your HTML template. If the image looks “off” or text gets cut, adjust the HTML/CSS in the image generator step before you assume Instagram is the problem.
Frequently Asked Questions
Plan on about 45 minutes if you already have your tokens and the Google Sheet ready.
No. You will connect accounts, paste API keys, and edit a couple of IDs in n8n.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in HCTI.io and any platform API usage depending on your volume.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and it’s a common tweak. You can disable the X posting step (the HTTP request that publishes the tweet update) and keep the Instagram media creation/publish steps intact. Many teams also customize the “Compose IG Caption” step to add a signature line, reorder hashtags, or pull a different column from the sheet. If you later want LinkedIn too, you can bolt on an extra publish step without changing the queue logic.
Most of the time it’s the credentials or permissions. Reconnect your Google Sheets credentials in n8n, confirm the Google account can access the sheet, and verify the Sheet ID and tab name match what’s inside the “Retrieve Sheet Records” and “Mark Sheet Posted” steps. If it works in a manual test but fails on schedule, double-check that the scheduled run is using the same credential set.
For most small teams, dozens of posts per day is fine, as long as your HCTI.io plan and social APIs allow it. n8n Cloud limits executions by plan, while self-hosting has no execution cap (it mainly depends on your server). If you queue hundreds of Pending rows at once, you’ll want batching so you don’t hit API rate limits.
Often, yes, because this workflow has a few moving parts (caption composition, HTML-to-image generation, two-step Instagram publishing, and status updates). n8n handles branching and multi-step logic cleanly, and self-hosting can be a big deal if you run frequent schedules. Zapier or Make can still work if you keep it simple, but the Instagram publishing side tends to get fiddly fast. If you’re trying to decide, look at how many credentials you’ll manage and how important the “Posted” audit trail is. Talk to an automation expert if you want help choosing.
Once this is running, your spreadsheet becomes a real publishing system, not a to-do list. Set it up, keep adding “Pending” rows, and move on to work that actually grows the account.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.