Quick Answer
Use Claude Code to build a small app with a backend that connects to the Walls.io API. Store your API token in an .env file, fetch posts through a server-side endpoint (to keep the token secure), and display them in your frontend as a social wall.

Building a social wall from scratch used to mean weeks of work: learning a different API for every social network, wrestling with OAuth flows, keeping up with breaking changes, and writing display code before you could show a single post. In this guide, we'll skip all of that. You'll use the Walls.io API to pull content from every network at once, and you'll use Claude Code, Anthropic's terminal-based AI coding agent, to write most of the code for you. By the end, you'll have a clean, self-refreshing social feed you can drop into an event screen, a website, or a piece of digital signage.
A social wall is a single feed that aggregates posts from many social media sources and displays them in one place. Once you can fetch that content programmatically, the use cases open up fast. Here are the three most common ones:
Here's the part that saves you the most time. Instead of integrating Facebook, Instagram, TikTok, YouTube, LinkedIn, and the rest one by one, you connect to a single Walls.io API that already speaks to all of them. Walls.io calls this a meta-API, and the advantages are real:
In short, you spend your time on the fun part (how the wall looks and behaves) instead of the plumbing.
Every API request identifies a specific wall through an access token. To create one, open your wall's settings in the Walls.io dashboard, look for the API section, and click Activate API access. You'll get a token that looks something like this:
8ad07e8ba0958191fa7b5842e4d270239f8b7cd
The API access feature is available on all paid Walls.io plans. You can check the current tiers on the Walls.io pricing page. Treat this token like a password. As you'll see below, we keep it on the server and never expose it in the browser.
All endpoints are prefixed with https://api.walls.io/v1. To build a feed, the only one you need is GET /posts. A minimal request looks like this:
GET https://api.walls.io/v1/posts?access_token=YOUR_TOKEN&fields=id,type,comment,external_fullname,post_image,post_link,created&limit=24&sort=-created
A few things worth knowing:
fields parameter keeps responses small by returning only what you ask for. Useful fields for a feed are comment (the post text), external_fullname (the author), type (the network), post_image (the attached image), post_link (the original post URL), and created (the timestamp).sort=-created to show the newest posts first.The pattern is the same in any language. First, check whether we have a local copy of the data that's less than five minutes old. If we do, use it. If not, call the API, save the fresh response to a local cache file, and render it. This keeps your wall fast, keeps you well under the rate limit, and keeps the wall online even if the API has a hiccup.
Save this as wall.php, drop in your token, and point your web server at it. It writes a cache file next to itself and renders a simple feed.
<?php
// ---- Configuration ----
$ACCESS_TOKEN = 'YOUR_WALLS_IO_ACCESS_TOKEN';
$CACHE_FILE = __DIR__ . '/wallsio-cache.json';
$CACHE_TTL = 300; // 5 minutes, in seconds
function get_wallsio_posts($token, $cacheFile, $ttl) {
// 1. Serve from cache if it is still fresh
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $ttl)) {
return json_decode(file_get_contents($cacheFile), true);
}
// 2. Otherwise fetch fresh data from the API
$fields = 'id,type,comment,external_fullname,post_image,post_link,created';
$url = 'https://api.walls.io/v1/posts'
. '?access_token=' . urlencode($token)
. '&fields=' . urlencode($fields)
. '&limit=24'
. '&sort=-created';
$response = @file_get_contents($url);
// 3. If the API is unreachable, fall back to a stale cache if we have one
if ($response === false) {
if (file_exists($cacheFile)) {
return json_decode(file_get_contents($cacheFile), true);
}
return ['data' => []];
}
// 4. Save the fresh response and return it
file_put_contents($cacheFile, $response);
return json_decode($response, true);
}
$result = get_wallsio_posts($ACCESS_TOKEN, $CACHE_FILE, $CACHE_TTL);
$posts = $result['data'] ?? [];
?>
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Our Social Wall</title></head>
<body>
<h1>What people are saying</h1>
<?php foreach ($posts as $post): ?>
<article>
<strong><?= htmlspecialchars($post['external_fullname'] ?? 'Someone') ?></strong>
<em>(<?= htmlspecialchars($post['type'] ?? '') ?>)</em>
<p><?= nl2br(htmlspecialchars($post['comment'] ?? '')) ?></p>
<?php if (!empty($post['post_image'])): ?>
<img src="<?= htmlspecialchars($post['post_image']) ?>" alt="" width="320">
<?php endif; ?>
<?php if (!empty($post['post_link'])): ?>
<p><a href="<?= htmlspecialchars($post['post_link']) ?>">View original post</a></p>
<?php endif; ?>
</article>
<hr>
<?php endforeach; ?>
</body>
</html>
This version uses Node.js with the built-in fetch (Node 18 or newer) and a tiny bit of Express to serve the page. Same logic: cache for five minutes, fall back to stale cache on failure, escape everything before rendering. Run npm install express first.
const express = require('express');
const fs = require('fs');
const path = require('path');
// ---- Configuration ----
const ACCESS_TOKEN = process.env.WALLSIO_TOKEN || 'YOUR_WALLS_IO_ACCESS_TOKEN';
const CACHE_FILE = path.join(__dirname, 'wallsio-cache.json');
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes, in milliseconds
const app = express();
async function getPosts() {
// 1. Serve from cache if it is still fresh
try {
const stat = fs.statSync(CACHE_FILE);
if (Date.now() - stat.mtimeMs < CACHE_TTL) {
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
}
} catch (e) { /* no cache yet, carry on */ }
// 2. Fetch fresh data from the API
const fields = 'id,type,comment,external_fullname,post_image,post_link,created';
const url = 'https://api.walls.io/v1/posts'
+ `?access_token=${encodeURIComponent(ACCESS_TOKEN)}`
+ `&fields=${encodeURIComponent(fields)}`
+ '&limit=24&sort=-created';
try {
const res = await fetch(url);
const json = await res.json();
fs.writeFileSync(CACHE_FILE, JSON.stringify(json)); // 3. Save to cache
return json;
} catch (e) {
// 4. On failure, fall back to a stale cache if we have one
if (fs.existsSync(CACHE_FILE)) {
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
}
return { data: [] };
}
}
function escapeHtml(str = '') {
return String(str).replace(/[&<>"']/g, c => ({
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
}[c]));
}
app.get('/', async (req, res) => {
const { data = [] } = await getPosts();
const items = data.map(p => `
<article>
<strong>${escapeHtml(p.external_fullname || 'Someone')}</strong>
<em>(${escapeHtml(p.type || '')})</em>
<p>${escapeHtml(p.comment || '')}</p>
${p.post_image ? `<img src="${escapeHtml(p.post_image)}" alt="" width="320">` : ''}
${p.post_link ? `<p><a href="${escapeHtml(p.post_link)}">View original post</a></p>` : ''}
</article><hr>`).join('');
res.send(`<!doctype html><html lang="en"><head><meta charset="utf-8">
<title>Our Social Wall</title></head><body>
<h1>What people are saying</h1>${items}</body></html>`);
});
app.listen(3000, () => console.log('Social wall running on http://localhost:3000'));
That's a complete, working social wall. Want it to refresh visually in the browser without a manual reload? Add a single line to the page's <head> that reloads it every five minutes, matching your cache interval:
<meta http-equiv="refresh" content="300">
Everything above is useful to understand, but you don't have to type it out. Claude Code can scaffold the whole thing from a good prompt. The trick is to give it the key facts it can't guess: the exact endpoint, the fields you want, the caching rule, and the CORS constraint. Here's a prompt you can paste straight into Claude Code:
Build a small social wall web app using the Walls.io API.
API details:
- Endpoint: GET https://api.walls.io/v1/posts
- Auth: pass my token as the query parameter access_token
- Request these fields: id,type,comment,external_fullname,post_image,post_link,created
- Use limit=24 and sort=-created (newest first)
- The API does NOT support CORS and the token must stay server-side,
so fetch on the server and serve rendered HTML to the browser.
Requirements:
- Cache the API response to a local file and only refetch when the
cache is older than 5 minutes.
- If the API call fails, fall back to the stale cache.
- Escape all post text and URLs before rendering (avoid XSS).
- Render a clean, simple feed: author, network, text, image, and a
link to the original post.
Read my token from an environment variable called WALLSIO_TOKEN.
Give me a Node.js version and a PHP version.
Claude Code will create the files, and you can then ask it to iterate in plain English: "make it a responsive grid," "add the network's icon next to each post," or "cache in Redis instead of a file." Because you gave it the API contract up front, it won't guess at the wrong endpoint or leak your token into client-side code.
With one API token and a few lines of cached, server-side code, you've got a social wall that pulls from every network at once and refreshes itself. The Walls.io meta-API removes the per-platform integration work, and Claude Code removes most of the typing. From here you can style the feed to match your brand, filter by media type or language, or push it to a big screen for your next event. The building blocks are the same. The rest is up to you.
Next up in this series: the same build, done with OpenAI Codex.
Brands using the Walls.io social wall API
Wallpaper from the 70s does a great job encouraging their buyers to share how they use the products. They then collect all this content from multiple social media platforms and incorporate it in their eCommerce website using the Walls.io social wall API.
→ What is a social media aggregator?
→ How do I embed a social media feed on a website?
→ What is a social media wall?