Pin a site to the member's menu
Pins a site to the member’s own menu, after their other pins. A pin changes nothing for the site’s owner, for anyone else it is shared with or for who may open the site by its address. Pinning a site that is already pinned answers 200 with the existing pin, even when the member has reached the limit of 50 pins and even when the member has since lost access to the site or removed it from their menu, so a retry of a request keeps its answer. A pin of a site the member can no longer open stays stored, counts toward the limit and shows in no menu until the site can be opened again.
A site the member cannot open, a site that is not in their menu and a site that does not exist are the same 404, so the request cannot be used to discover sites. To make a new pin, a site the member removed from their menu and a member who has 50 pins already are 422. The member’s own drafts can be pinned.
A bearer with write access only: a request on the cookie mount is refused with 403, with or without an X-Fluid-Member-Site header, and so is a member or portal JWT.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/site-pins \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67"
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/site-pins"
payload = { "site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({site_id: '0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67'})
};
fetch('https://api.fluid.app/api/member/v2026-10/site-pins', 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/member/v2026-10/site-pins",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'site_id' => '0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/member/v2026-10/site-pins"
payload := strings.NewReader("{\n \"site_id\": \"0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/member/v2026-10/site-pins")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"site_id\": \"0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/site-pins")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"site_id\": \"0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d91",
"site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67",
"created_at": "2026-09-30T15:00:00.000000Z"
},
"meta": {
"request_uuid": "0192f4c8-5b6c-7d74-a3e8-0f1a2b3c4d5e",
"timestamp": "2026-09-30T15:08:21Z"
}
}{
"status": 201,
"data": {
"id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d91",
"site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67",
"created_at": "2026-09-30T15:08:21.000000Z"
},
"meta": {
"request_uuid": "0192f4c8-5b6c-7d74-a3e8-0f1a2b3c4d5e",
"timestamp": "2026-09-30T15:08:21Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
A member credential in the Authorization: Bearer header: a member
session JWT, a portal JWT whose login is linked to a membership in
that company, an opaque member token, or a verified One Auth identity
access token. The credential alone identifies the member and company.
Member session and portal JWTs are read-only and are refused with 403
on every write.
Body
The site to pin to the member's menu. Any other field is refused as an unknown field.
Public id of the site, as listed in the member's menu.
Response
The site was already pinned. The existing pin.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/site-pins \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67"
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/site-pins"
payload = { "site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({site_id: '0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67'})
};
fetch('https://api.fluid.app/api/member/v2026-10/site-pins', 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/member/v2026-10/site-pins",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'site_id' => '0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/member/v2026-10/site-pins"
payload := strings.NewReader("{\n \"site_id\": \"0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/member/v2026-10/site-pins")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"site_id\": \"0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/site-pins")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"site_id\": \"0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d91",
"site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67",
"created_at": "2026-09-30T15:00:00.000000Z"
},
"meta": {
"request_uuid": "0192f4c8-5b6c-7d74-a3e8-0f1a2b3c4d5e",
"timestamp": "2026-09-30T15:08:21Z"
}
}{
"status": 201,
"data": {
"id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d91",
"site_id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67",
"created_at": "2026-09-30T15:08:21.000000Z"
},
"meta": {
"request_uuid": "0192f4c8-5b6c-7d74-a3e8-0f1a2b3c4d5e",
"timestamp": "2026-09-30T15:08:21Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}