Parallèle Docs
Api

Blog

API reference for blog endpoints.

Blog API

The blog API provides endpoints for fetching published blog posts.

List Blog Posts

Fetch published blog posts with pagination.

GET /api/public/blog

Query Parameters

ParameterTypeRequiredDescription
localestringNoFilter by locale
limitnumberNoMax posts to return (default: 20, max: 100)
offsetnumberNoPagination offset (default: 0)

Example

curl "https://parallele.ai/api/public/blog?locale=en&limit=10" \
  -H "x-api-key: prl_xxx"

Response:

{
  "posts": [
    {
      "slug": "introducing-parallele-2",
      "locale": "en",
      "title": "Introducing Parallèle 2.0",
      "excerpt": "We're excited to announce the next major version of Parallèle...",
      "featuredImage": "https://cdn.example.com/blog/parallele-2.jpg",
      "author": "John Doe",
      "publishedAt": "2025-01-20T10:00:00Z",
      "meta": {
        "title": "Introducing Parallèle 2.0 | Blog",
        "description": "We're excited to announce the next major version..."
      }
    },
    {
      "slug": "content-management-best-practices",
      "locale": "en",
      "title": "Content Management Best Practices",
      "excerpt": "Learn how to structure your content for maximum efficiency...",
      "featuredImage": "https://cdn.example.com/blog/best-practices.jpg",
      "author": "Jane Smith",
      "publishedAt": "2025-01-15T14:30:00Z",
      "meta": {
        "title": "Content Management Best Practices | Blog",
        "description": "Learn how to structure your content..."
      }
    }
  ],
  "total": 24,
  "hasMore": true
}

Get Single Post

Fetch a specific blog post by slug.

GET /api/public/blog/:slug

Path Parameters

ParameterTypeRequiredDescription
slugstringYesPost slug

Query Parameters

ParameterTypeRequiredDescription
localestringNoLocale code

Example

curl "https://parallele.ai/api/public/blog/introducing-parallele-2?locale=en" \
  -H "x-api-key: prl_xxx"

Response:

{
  "post": {
    "slug": "introducing-parallele-2",
    "locale": "en",
    "title": "Introducing Parallèle 2.0",
    "excerpt": "We're excited to announce the next major version of Parallèle...",
    "content": "<p>After months of development, we're thrilled to release...</p>",
    "featuredImage": "https://cdn.example.com/blog/parallele-2.jpg",
    "author": {
      "name": "John Doe",
      "avatar": "https://cdn.example.com/team/john.jpg"
    },
    "publishedAt": "2025-01-20T10:00:00Z",
    "updatedAt": "2025-01-20T10:00:00Z",
    "meta": {
      "title": "Introducing Parallèle 2.0 | Blog",
      "description": "We're excited to announce the next major version..."
    }
  }
}

Pagination Example

Implement infinite scroll or "Load More":

"use client";
 
import { useState, useEffect } from "react";
 
export function BlogList({ initialPosts, initialHasMore }) {
  const [posts, setPosts] = useState(initialPosts);
  const [hasMore, setHasMore] = useState(initialHasMore);
  const [loading, setLoading] = useState(false);
 
  async function loadMore() {
    setLoading(true);
    const res = await fetch(`/api/blog?offset=${posts.length}&limit=10`);
    const data = await res.json();
    setPosts([...posts, ...data.posts]);
    setHasMore(data.hasMore);
    setLoading(false);
  }
 
  return (
    <div>
      {posts.map(post => (
        <BlogCard key={post.slug} post={post} />
      ))}
      {hasMore && (
        <button onClick={loadMore} disabled={loading}>
          {loading ? "Loading..." : "Load More"}
        </button>
      )}
    </div>
  );
}

RSS Feed

Generate an RSS feed from blog posts:

app/blog/rss.xml/route.ts
import { parallele } from "@/lib/parallele";
 
export async function GET() {
  const { posts } = await parallele.getBlogPosts("en", { limit: 50 });
 
  const rss = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>My Blog</title>
    <link>https://example.com/blog</link>
    <description>Latest posts from our blog</description>
    ${posts.map(post => `
    <item>
      <title>${escapeXml(post.title)}</title>
      <link>https://example.com/blog/${post.slug}</link>
      <pubDate>${new Date(post.publishedAt).toUTCString()}</pubDate>
      <description>${escapeXml(post.excerpt)}</description>
    </item>
    `).join("")}
  </channel>
</rss>`;
 
  return new Response(rss, {
    headers: { "Content-Type": "application/rss+xml" },
  });
}

On this page