Most social media automation tools assume your data lives in a spreadsheet. But what if your data lives in a CMS, a booking system, a weather API, or a custom backend?
Storylayer connects directly to any JSON API — no spreadsheet required. You map your data fields to a visual template once, set a posting schedule, and Storylayer handles the rest. Every day, new data in, new post out.
This guide walks through the exact setup used by LuxSki, a luxury ski resort discovery platform that publishes daily powder condition reports to Instagram, Facebook, and X — automatically, from their own Sanity CMS.
What You'll Need
- A Storylayer account
- A JSON API endpoint that returns your data (publicly accessible or with an API key)
- A Creatomate template (or use one of Storylayer's built-in templates)
- Connected social accounts (Instagram, Facebook, X, or Ghost)
Step 1 — Connect Your Social Accounts
Before building your first story, connect the channels you want to post to.
Go to Dashboard → Social Accounts and connect Instagram, Facebook, X, or Ghost. Storylayer uses long-lived tokens so you won't need to reconnect frequently.
Tip: Instagram requires a Professional or Creator account. Personal accounts cannot be connected for publishing.
Step 2 — Create a New Story
From your dashboard, click Create Story. Give it a name — something descriptive like "LuxSki Daily Powder Report" — and select the channels you want to post to.
You'll move through a 4-step wizard:
- Channels & Setup
- Data & Schedule
- Configure Channels
- Review & Activate
Step 3 — Connect Your API as the Data Source
On the Data & Schedule step, select Custom API as your data source.
Enter your API endpoint URL. Storylayer will fetch a sample response immediately and display the available fields. For LuxSki, this looks like:
https://api.luxski.com/v1/resorts/powder-picks?date=today
Once the fetch completes, you'll see a confirmation:
✅ 34 fields loaded from your data source. You can now proceed to map fields to your template.
The fields available from a typical ski resort API might include:
| Field | Example Value |
|---|---|
| resortName | Aspen Snowmass |
| freshSnowfall | 14" overnight |
| baseDepth | 72" |
| destinationPhoto | https://cdn.sanity.io/... |
| trailsOpen | 187 of 336 |
| topElevation | 11,212 ft |
| reportDate | March 11, 2026 |
| hotelUrl | https://luxski.com/aspen |
Important: Make sure your data loads before clicking Next. The Next button stays disabled until Storylayer confirms fields are available. This ensures your field mapping dropdowns are populated on the next step.
Scheduling
Set your posting schedule on this same step. For a daily powder report, set:
- Trigger: Scheduled
- Frequency: Daily
- Time: 6:00 AM (before skiers check conditions for the day)
Step 4 — Configure Each Channel
The Configure Channels step is where Storylayer becomes powerful. Each channel — Instagram, Facebook, X, Ghost — gets its own tab with independent settings.
Choose Your Content Type
For each channel, select how you want the post to look:
- Template + caption — a branded visual rendered from your Creatomate template, with an AI-written or data-pulled caption
- Photo + caption — a photo from your data source with a caption
- Caption only — text post, no image
For LuxSki's Instagram and Facebook posts, the choice is Template + caption. For X, Photo + caption works well for a quick daily update.
Select Your Template
Click the template you want to use. If you've built a custom Creatomate template for your brand, it will appear here. If not, Storylayer's built-in templates are a good starting point.
For LuxSki, the template includes fields for:
- Resort name
- Overnight snowfall total
- Base depth
- Open trails count
- A full-bleed resort photo
Map Your Data Fields
Once you select a template, Storylayer shows a field mapping table. On the left are the template's element names. On the right are dropdowns listing every field from your API.
For LuxSki, the mapping looks like:
| Template Field | API Field |
|---|---|
| Resort-Name.text | resortName |
| Snowfall.text | freshSnowfall |
| Base-Depth.text | baseDepth |
| Trails-Open.text | trailsOpen |
| Hero-Image.source | destinationPhoto |
As you map each field, the live preview on the right updates in real time — showing exactly what the final post will look like with your real data inside your template.
This is the most important step. If the preview looks right, the post will look right.
Set the Caption
Under the field mapping, set how the caption is generated:
- From data — pulls a field directly from your API (e.g. a
descriptionorcaptionfield) - AI-generated — Storylayer writes a caption using GPT-4o based on your data and tone settings
- Write it myself — type a static caption (not recommended for daily automation)
For LuxSki's powder reports, AI-generated captions work extremely well. The tone is set to Luxury & aspirational, with guidance like:
"Always mention the resort name and overnight snowfall. Use evocative language — fresh tracks, untouched powder, first chair. Never use generic filler phrases."
Configure Ghost (Blog)
If you're also posting to a Ghost blog, the Ghost tab works differently. Instead of a visual template, you configure:
- Cover photo — pulled from your API's image field
- Article length — Short summary, Standard post, or Long-form article
- Tone — Editorial, Conversational, etc.
- Publish status — Publish immediately or Save as draft
Storylayer writes a full blog article using your API data as the source, with your tone settings applied. For LuxSki, this means a 500-word daily conditions report published to their Ghost blog every morning — written entirely by AI from raw snow data.
Step 5 — Review & Activate
The final step shows a summary of every channel's configuration. Review the template preview, caption style, and schedule one more time.
When everything looks right, click Activate.
Storylayer will:
- Fetch fresh data from your API on the schedule you set
- Render your Creatomate template with the latest data
- Generate captions using AI (or pull them from your data)
- Post to every connected channel simultaneously
- Log each post to your Content Library automatically
What LuxSki's Daily Automation Looks Like
Every morning at 6:00 AM, LuxSki's automation runs:
- Fetches that day's resort data from their Sanity CMS
- Renders a branded Instagram graphic with overnight snowfall, base depth, and a hero resort photo
- Posts to Instagram with a luxury-toned AI caption and branded hashtags
- Posts the same graphic to Facebook with a slightly longer caption
- Posts a text + photo update to X
- Publishes a full conditions report article to their Ghost blog
No manual posting required. The on-mountain team updates conditions in their CMS. Storylayer handles everything else.
Common Questions
What if my API requires authentication?
Storylayer supports API key authentication via request headers. When connecting your data source, add your API key as a custom header (e.g. Authorization: Bearer YOUR_KEY).
What if my data changes throughout the day? You can set the schedule to run multiple times per day — hourly, twice daily, or on a custom interval. Each run fetches fresh data.
What if my image URL has query parameters? Storylayer handles image URLs with query parameters correctly — including crop and resize parameters from CDNs like Sanity, Cloudinary, and Imgix.
Can I use multiple templates for different channels? Yes. Instagram and Facebook can use different Creatomate templates. X can use a photo-only layout. Ghost uses its own article format. Each channel is configured independently.
What if no new data is available on a given day? If your API returns the same record as the previous run, Storylayer's deduplication system will skip it to avoid posting duplicate content.
Ready to Connect Your Data?
If your business runs on live data — conditions reports, listings, inventory, schedules, prices — Storylayer turns it into daily social content automatically.
Start your free trial → See more use cases →
Related guides: