Public Posts (blog) catalog
Unauthenticated. Company is resolved from the request subdomain. Returns ONLY live posts (active + resolved-published, country-eligible, language-eligible, not discarded).
Posts are presented on the storefront as the blog — the
canonical storefront URLs use /home/blog and
/home/blog/:slug, even though the API resource is posts.
curl --request GET \
--url https://api.fluid.app/api/v202604/postsimport requests
url = "https://api.fluid.app/api/v202604/posts"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.fluid.app/api/v202604/posts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/v202604/posts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/posts"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.fluid.app/api/v202604/posts")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/posts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"status": 200,
"meta": {
"request_id": "7f3c9a1e-52d4-4b8e-9c61-2a8e4f0d7b35",
"timestamp": "2026-09-22T14:08:31Z",
"pagination": {
"cursor": null,
"limit": 25,
"prev_cursor": null,
"next_cursor": null
}
},
"posts": [
{
"id": 8856,
"slug": "scranton-branch-mug-restock",
"title": "The Scranton Branch Mug Is Back",
"description": "Our most-requested piece of merch is back in stock, just in time for the holidays.",
"image_url": "https://cdn.fluid.app/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"canonical_url": "https://shop.dundermifflin.com/home/blog/scranton-branch-mug-restock",
"images": {
"thumb": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-200,c-at_max,f-auto,q-70/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"width": 200
},
"medium": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-600,c-at_max,f-auto,q-75/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"width": 600
},
"large": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-1200,c-at_max,f-auto,q-80/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"width": 1200
}
},
"active": true,
"status": "published",
"publish_at": null,
"created_at": "2026-09-16T14:12:45Z",
"updated_at": "2026-09-17T09:00:00Z",
"seo": {
"title": "The Scranton Branch Mug Is Back",
"description": "Our most-requested piece of merch is back in stock, just in time for the holidays.",
"image_url": "https://ik.imagekit.io/fluidapp/tr:w-1200,h-630,c-maintain_ratio,fo-auto,f-auto,q-80/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"indexable": true
},
"metafields": [],
"languages": [
"en"
],
"countries": [],
"summary": "The Scranton Branch Mug sold out in a week. A fresh batch just landed.",
"post_date": "2026-09-17",
"post_author": "Pam Beesly",
"category_id": 3112,
"collection_ids": [
5207,
5211
]
},
{
"id": 8841,
"slug": "choosing-the-right-paper-weight",
"title": "Choosing the Right Paper Weight",
"description": "20lb, 24lb, or cardstock? A practical guide to picking paper for every job in the office.",
"image_url": "https://cdn.fluid.app/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"canonical_url": "https://shop.dundermifflin.com/home/blog/choosing-the-right-paper-weight",
"images": {
"thumb": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-200,c-at_max,f-auto,q-70/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"width": 200
},
"medium": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-600,c-at_max,f-auto,q-75/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"width": 600
},
"large": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-1200,c-at_max,f-auto,q-80/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"width": 1200
}
},
"active": true,
"status": "published",
"publish_at": null,
"created_at": "2026-09-09T16:30:00Z",
"updated_at": "2026-09-10T08:00:00Z",
"seo": {
"title": "Choosing the Right Paper Weight",
"description": "20lb, 24lb, or cardstock? A practical guide to picking paper for every job in the office.",
"image_url": "https://ik.imagekit.io/fluidapp/tr:w-1200,h-630,c-maintain_ratio,fo-auto,f-auto,q-80/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"indexable": true
},
"metafields": [],
"languages": [
"en",
"es"
],
"countries": [],
"summary": "Most offices only need 20lb paper. Here is when to reach for something heavier.",
"post_date": "2026-09-10",
"post_author": "Dwight Schrute",
"category_id": 3108,
"collection_ids": [
5207
]
}
]
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"pagination": {
"cursor": "<string>",
"limit": 25,
"prev_cursor": "<string>",
"next_cursor": "<string>"
}
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"pagination": {
"cursor": "<string>",
"limit": 25,
"prev_cursor": "<string>",
"next_cursor": "<string>"
}
}
}Query Parameters
Response locale. ISO code (e.g. fr, de). When omitted,
responds in the company's default locale. On reads an
unsupported or unknown locale is ignored — the response comes
back in the default locale, never a 422. Any translated field
with no value in the requested locale falls back to its en
value.
"fr"
Free-text search over
translation-aware title and description fields, plus slug.
On /products it additionally matches the product-level sku and
every variant SKU.
On /products the match is TIERED: the term is matched first against
the fields that NAME a product — title in every locale, slug, sku
and every variant SKU — and description / metafields answer only when
no name match survives the other filters on the request. A bundle's copy
lists the products it contains, so matching name and copy in one pass
returned every pack that merely mentions a product ahead of the product
itself.
Substring-aware (word_middle), so partial terms match. Results are
returned in the requested sort order, not by relevance — search
resolves to an id set that the ordinary paginated query then filters,
and that id set is capped at 1000 matches per request.
Opaque cursor returned in meta.pagination.next_cursor (or
prev_cursor). Omit on the first page.
Page size. Default 25. Max 100. Requests above 100 return 422.
1 <= x <= 100ISO-2 country code. Restricts the catalog to resources available
in that country — combining the with_country_iso scope's
OR-empty semantics: unrestricted resources (no access_countries
rows) match every country.
"GB"
ISO locale. Restricts the catalog to resources translated in that locale.
"fr"
Restrict the catalog to posts filed under one Category.
Restrict the catalog to posts appearing in one Collection.
Single sort key. Prefix with - for descending. Default
sort is newest blog posts first (post_date DESC NULLS LAST).
post_date, -post_date, title, -title, created_at, -created_at, updated_at, -updated_at Response
A page of live posts.
Shared success envelope for list / show / create / update
responses: the resource payload is returned alongside a top-level
integer status and meta. Composed onto each resource response
via allOf.
curl --request GET \
--url https://api.fluid.app/api/v202604/postsimport requests
url = "https://api.fluid.app/api/v202604/posts"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.fluid.app/api/v202604/posts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/v202604/posts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/posts"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.fluid.app/api/v202604/posts")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/posts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"status": 200,
"meta": {
"request_id": "7f3c9a1e-52d4-4b8e-9c61-2a8e4f0d7b35",
"timestamp": "2026-09-22T14:08:31Z",
"pagination": {
"cursor": null,
"limit": 25,
"prev_cursor": null,
"next_cursor": null
}
},
"posts": [
{
"id": 8856,
"slug": "scranton-branch-mug-restock",
"title": "The Scranton Branch Mug Is Back",
"description": "Our most-requested piece of merch is back in stock, just in time for the holidays.",
"image_url": "https://cdn.fluid.app/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"canonical_url": "https://shop.dundermifflin.com/home/blog/scranton-branch-mug-restock",
"images": {
"thumb": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-200,c-at_max,f-auto,q-70/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"width": 200
},
"medium": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-600,c-at_max,f-auto,q-75/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"width": 600
},
"large": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-1200,c-at_max,f-auto,q-80/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"width": 1200
}
},
"active": true,
"status": "published",
"publish_at": null,
"created_at": "2026-09-16T14:12:45Z",
"updated_at": "2026-09-17T09:00:00Z",
"seo": {
"title": "The Scranton Branch Mug Is Back",
"description": "Our most-requested piece of merch is back in stock, just in time for the holidays.",
"image_url": "https://ik.imagekit.io/fluidapp/tr:w-1200,h-630,c-maintain_ratio,fo-auto,f-auto,q-80/dunder-mifflin/posts/scranton-branch-mug-restock.jpg",
"indexable": true
},
"metafields": [],
"languages": [
"en"
],
"countries": [],
"summary": "The Scranton Branch Mug sold out in a week. A fresh batch just landed.",
"post_date": "2026-09-17",
"post_author": "Pam Beesly",
"category_id": 3112,
"collection_ids": [
5207,
5211
]
},
{
"id": 8841,
"slug": "choosing-the-right-paper-weight",
"title": "Choosing the Right Paper Weight",
"description": "20lb, 24lb, or cardstock? A practical guide to picking paper for every job in the office.",
"image_url": "https://cdn.fluid.app/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"canonical_url": "https://shop.dundermifflin.com/home/blog/choosing-the-right-paper-weight",
"images": {
"thumb": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-200,c-at_max,f-auto,q-70/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"width": 200
},
"medium": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-600,c-at_max,f-auto,q-75/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"width": 600
},
"large": {
"url": "https://ik.imagekit.io/fluidapp/tr:w-1200,c-at_max,f-auto,q-80/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"width": 1200
}
},
"active": true,
"status": "published",
"publish_at": null,
"created_at": "2026-09-09T16:30:00Z",
"updated_at": "2026-09-10T08:00:00Z",
"seo": {
"title": "Choosing the Right Paper Weight",
"description": "20lb, 24lb, or cardstock? A practical guide to picking paper for every job in the office.",
"image_url": "https://ik.imagekit.io/fluidapp/tr:w-1200,h-630,c-maintain_ratio,fo-auto,f-auto,q-80/dunder-mifflin/posts/choosing-the-right-paper-weight.jpg",
"indexable": true
},
"metafields": [],
"languages": [
"en",
"es"
],
"countries": [],
"summary": "Most offices only need 20lb paper. Here is when to reach for something heavier.",
"post_date": "2026-09-10",
"post_author": "Dwight Schrute",
"category_id": 3108,
"collection_ids": [
5207
]
}
]
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"pagination": {
"cursor": "<string>",
"limit": 25,
"prev_cursor": "<string>",
"next_cursor": "<string>"
}
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"pagination": {
"cursor": "<string>",
"limit": 25,
"prev_cursor": "<string>",
"next_cursor": "<string>"
}
}
}