facebook pixel
Gondola Logo

Developer API

Portfolio API

Use this API to fetch a Gondola profile summary, aggregate stats, and credited public posts from Gondola for a custom portfolio site or agent workflow. The stats always reflect the current request criteria, so overall portfolio totals should come from an unfiltered fetch.

Send a portfolio token in the Authorization header as a Bearer token. Client-side browser requests are supported, but anyone who can inspect your page can also see the token. Gondola enforces a 60 requests per 60 seconds rate limit per token.

Share this docs URL with your coding agent

https://gondola.cc/docs/api/portfolio

This page provides the human-oriented integration guidance, links to machine-readable OpenAPI formats, and explains the trade-off of exposing a read-only portfolio token in client-side code.

Suggested agent prompt

I want to create a personal portfolio website that highlights my stats and posts from Gondola. Here is how the API works:

Endpoint: GET https://gondola.cc/api/v1/portfolio
Auth: Send an Authorization: Bearer <token> header (I will give you the token value).
CORS: Enabled for any origin — direct browser fetch() works.
Response shape: { success: 1, data: { user, stats, posts, paging, access } }
- data.user: { name, username, avatarUrl, blurb, defaultRole: { id, name } | null, profileUrl }
- data.stats: { postCount, views, likes, shares, comments }
- data.posts: array of { id, url, gondolaUrl, thumbnailUrl, account, network, type, postedAt, views, likes, shares, comments, credits }
- data.posts[].credits: array of { user: { name, username, avatarUrl }, role: { name } }
- data.access: { tier, isPro } — "free" tier returns max 5 posts

Rules:
- Embed the token as a JavaScript string constant. Do NOT use process.env — this runs in the browser.
- Fetch once on page load and cache the result. Do not re-fetch on every render.
- Do NOT send sort, network, account, collaborator, or role query params unless data.access.isPro is true — the server returns 403.
- Handle HTTP 429 gracefully — show cached or placeholder content instead of an error.
- thumbnailUrl and avatarUrl are complete image URLs ready for <img src>.

Full OpenAPI spec for reference: https://gondola.cc/docs/api/openapi/portfolio.json

Free Tier

  • Returns full stats plus the 5 most recent credited public posts.
  • Ignores pagination requests beyond the first page.

PRO Tier

  • Returns full stats plus the full paginated credited post feed.
  • Honors from and size query parameters.
  • Supports filtering posts by network, account, role, and collaborator.
  • Filtered requests return stats for the filtered subset, not all-time totals.

Pagination

  • Use the from query parameter as a zero-based offset.
  • Use the size query parameter to request a page size.
  • Use data.paging.nextFrom to continue fetching for PRO users.
  • If you need overall top-line stats on a portfolio page, keep them from an unfiltered request.

cURL Example

curl --request GET \
  --url https://gondola.cc/api/v1/portfolio \
  --header 'Accept: application/json' \
  --header "Authorization: Bearer $GONDOLA_PORTFOLIO_TOKEN"

TypeScript Example

// Paste your portfolio token here as a string constant.
// Do NOT use process.env — this runs in the browser.
const PORTFOLIO_TOKEN = 'gpf_your_token_here';

const response = await fetch('https://gondola.cc/api/v1/portfolio', {
  headers: {
    Accept: 'application/json',
    Authorization: `Bearer ${PORTFOLIO_TOKEN}`,
  },
});

if (response.status === 429) {
  const retryAfter = response.headers.get('Retry-After') || '60';
  console.warn(`Rate limited. Retry after ${retryAfter}s`);
} else if (!response.ok) {
  const err = await response.json();
  throw new Error(err.message || `Request failed: ${response.status}`);
} else {
  // All data is nested inside payload.data
  const { data } = await response.json();
  const { user, stats, posts } = data;
  // user.name, stats.views, posts[0].thumbnailUrl, etc.
}