Authentication

All API requests require a valid Bearer token passed in the Authorization header. API keys are managed from your account at /apiKeys. The endpoints /api/docs and /api/spec are publicly accessible and do not require authentication.

Header format: Authorization: Bearer YOUR_API_KEY

Keep your API key secret. Do not include it in client-side code or public repositories. Keys can be revoked and regenerated at any time from the API Keys page.

Base URL

All endpoints are relative to the following base URL:

https://pagerankcafe.com

All requests and responses use JSON. Include the header Content-Type: application/json on POST requests.

Access Levels

API access is gated by your membership level. Free members can use all read endpoints. Write endpoints require a paid membership.

Level Read Endpoints Write Endpoints
Free member Yes No
Paid member Yes Yes

Error Responses

All errors return a JSON object with a single error key describing what went wrong.

Error format
{"error": "description of the error"}
HTTP Status Meaning
400 Validation error — a required field is missing or invalid.
401 Unauthorized — missing or invalid API key.
403 Forbidden — paid membership required for this endpoint.
405 Method not allowed — wrong HTTP method used for this endpoint.

General

GET /api/health All members API status and user info

Returns the current API status along with basic information about the authenticated user, including their username and membership level.

curl -X GET https://pagerankcafe.com/api/health \
  -H "Authorization: Bearer YOUR_API_KEY"
import requests

url = "https://pagerankcafe.com/api/health"
headers = {"Authorization": "Bearer YOUR_API_KEY"}

response = requests.get(url, headers=headers)
print(response.json())
$ch = curl_init("https://pagerankcafe.com/api/health");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
const response = await fetch("https://pagerankcafe.com/api/health", {
  headers: {
    "Authorization": "Bearer YOUR_API_KEY"
  }
});
const data = await response.json();
console.log(data);
Response
200 OK
{
  "status": "ok",
  "user": "johndoe",
  "membership": "upgraded"
}

Read Endpoints

All members: The following endpoints are available to free and paid members alike.
GET /api/banners All members User's active banners

Returns all active banner advertisements belonging to the authenticated user, including impression counts, click counts, and computed click-through rate.

curl -X GET https://pagerankcafe.com/api/banners \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://pagerankcafe.com/api/banners",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = response.json()
$ch = curl_init("https://pagerankcafe.com/api/banners");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/banners", {
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});
const { banners } = await response.json();
Response
200 OK
{
  "banners": [
    {
      "id": "1",
      "title": "My Banner",
      "url": "https://example.com/banner.png",
      "url_target": "https://example.com",
      "impressions": "100",
      "clicks": "5",
      "ctr": "5.00"
    }
  ]
}
GET /api/youtube-ads All members User's active YouTube ads

Returns all active YouTube video advertisements belonging to the authenticated user, along with view counts and the number of active post slots.

curl -X GET https://pagerankcafe.com/api/youtube-ads \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://pagerankcafe.com/api/youtube-ads",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = response.json()
$ch = curl_init("https://pagerankcafe.com/api/youtube-ads");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/youtube-ads", {
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});
const { youtube_ads } = await response.json();
Response
200 OK
{
  "youtube_ads": [
    {
      "id": "1",
      "title": "My Video",
      "video_url": "https://youtube.com/watch?v=abc123",
      "views": "50",
      "youtube_ad_post_count": "2"
    }
  ]
}
GET /api/press-releases All members User's active press releases

Returns all active press release articles belonging to the authenticated user, including their public slug, source URL, view counts, and number of active post slots.

curl -X GET https://pagerankcafe.com/api/press-releases \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://pagerankcafe.com/api/press-releases",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = response.json()
$ch = curl_init("https://pagerankcafe.com/api/press-releases");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/press-releases", {
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});
const { press_releases } = await response.json();
Response
200 OK
{
  "press_releases": [
    {
      "id": "1",
      "title": "My Article",
      "slug": "my-article",
      "url": "https://example.com",
      "views": "30",
      "post_count": "1"
    }
  ]
}
GET /api/credits All members Credit balance

Returns the authenticated user's current credit balance, available post slots, links viewed today, and remaining links to view for the day.

curl -X GET https://pagerankcafe.com/api/credits \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://pagerankcafe.com/api/credits",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = response.json()
print(data["credits"]["available_credits"])
$ch = curl_init("https://pagerankcafe.com/api/credits");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/credits", {
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});
const { credits } = await response.json();
Response
200 OK
{
  "credits": {
    "available_credits": 150,
    "available_posts": 15,
    "links_viewed": 0,
    "links_remaining": 10
  }
}
GET /api/referral-stats All members Referral counts by period

Returns referral signup counts for the authenticated user broken down by time period: today, last 7 days, last 30 days, and all-time total.

curl -X GET https://pagerankcafe.com/api/referral-stats \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://pagerankcafe.com/api/referral-stats",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = response.json()
$ch = curl_init("https://pagerankcafe.com/api/referral-stats");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_API_KEY"
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/referral-stats", {
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});
const { referrals } = await response.json();
Response
200 OK
{
  "referrals": {
    "today": 0,
    "last_7_days": 2,
    "last_30_days": 5,
    "all_time": 12
  }
}

Write Endpoints

Paid membership required: The following endpoints are only available to paid members. Free members will receive a 403 response.
POST /api/banners/create Create a banner ad

Creates a new banner advertisement. The image URL must use HTTPS and resolve to an image matching one of the supported dimensions. Creating a banner does not post it to rotation — use /api/banners/post after creation to activate it.

Parameters
Field Type Required Description
title string Required Display name for the banner.
url string Required HTTPS URL to the banner image. Must match a supported dimension.
url_target string Required Destination URL users are taken to when clicking the banner.
Supported banner dimensions: 728x90, 300x250, 120x600, 160x600, 468x60, 336x280, 250x250, 851x315, 650x400, 800x82, 234x60, 125x125, 300x200, 120x240, 240x400, 150x60
curl -X POST https://pagerankcafe.com/api/banners/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My Banner",
    "url": "https://example.com/banner.png",
    "url_target": "https://example.com"
  }'
response = requests.post(
    "https://pagerankcafe.com/api/banners/create",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    },
    json={
        "title": "My Banner",
        "url": "https://example.com/banner.png",
        "url_target": "https://example.com"
    }
)
data = response.json()
$payload = json_encode([
    'title'      => 'My Banner',
    'url'        => 'https://example.com/banner.png',
    'url_target' => 'https://example.com'
]);
$ch = curl_init("https://pagerankcafe.com/api/banners/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer YOUR_API_KEY',
    'Content-Type: application/json'
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/banners/create", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    title: "My Banner",
    url: "https://example.com/banner.png",
    url_target: "https://example.com"
  })
});
const data = await response.json();
Response
201 Created
{
  "status": "created",
  "banner": {
    "id": "1",
    "title": "My Banner",
    "url": "https://example.com/banner.png",
    "url_target": "https://example.com",
    "location": "TOP_BOTTOM"
  }
}
POST /api/banners/post Post a banner into rotation

Activates an existing banner ad by posting it into the rotation for the specified number of days. Paid members can post for 1 to 2 days at a cost of 10 credits (1 post point) per day.

Parameters
Field Type Required Description
banner_id integer Required ID of the banner to post. Must belong to the authenticated user.
days integer Optional Number of days to post the banner. Default is 1. Paid members: 1-2.
curl -X POST https://pagerankcafe.com/api/banners/post \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"banner_id": 1, "days": 2}'
response = requests.post(
    "https://pagerankcafe.com/api/banners/post",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    },
    json={"banner_id": 1, "days": 2}
)
data = response.json()
$payload = json_encode(['banner_id' => 1, 'days' => 2]);
$ch = curl_init("https://pagerankcafe.com/api/banners/post");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer YOUR_API_KEY',
    'Content-Type: application/json'
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/banners/post", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ banner_id: 1, days: 2 })
});
const data = await response.json();
Response
200 OK
{
  "status": "posted",
  "banner_post": {
    "banner_id": "1",
    "days": "2",
    "start_date": "2026-01-01 00:00:00",
    "end_date": "2026-01-03 00:00:00"
  }
}
POST /api/press-releases/create Create a press release

Creates a new press release article. The slug must be unique across the platform and will form part of the public URL at /blog/<slug>. The body field accepts HTML. Creating a press release does not publish it — use /api/press-releases/post to submit it for activation.

Parameters
Field Type Required Description
title string Required Article headline.
url string Required HTTPS source URL for the article.
intro string Required Short introductory summary displayed in article listings.
body string (HTML) Required Full article body. Accepts HTML markup.
slug string Required URL-safe identifier, must be unique. Example: my-article-title.
meta_description string Optional SEO meta description for the article page.
curl -X POST https://pagerankcafe.com/api/press-releases/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My Article",
    "url": "https://example.com/source",
    "intro": "A short summary of the article.",
    "body": "<p>Full article content here.</p>",
    "slug": "my-article",
    "meta_description": "SEO description for this article."
  }'
response = requests.post(
    "https://pagerankcafe.com/api/press-releases/create",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    },
    json={
        "title": "My Article",
        "url": "https://example.com/source",
        "intro": "A short summary of the article.",
        "body": "<p>Full article content here.</p>",
        "slug": "my-article",
        "meta_description": "SEO description for this article."
    }
)
data = response.json()
$payload = json_encode([
    'title'            => 'My Article',
    'url'              => 'https://example.com/source',
    'intro'            => 'A short summary of the article.',
    'body'             => '<p>Full article content here.</p>',
    'slug'             => 'my-article',
    'meta_description' => 'SEO description for this article.'
]);
$ch = curl_init("https://pagerankcafe.com/api/press-releases/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer YOUR_API_KEY',
    'Content-Type: application/json'
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/press-releases/create", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    title: "My Article",
    url: "https://example.com/source",
    intro: "A short summary of the article.",
    body: "<p>Full article content here.</p>",
    slug: "my-article",
    meta_description: "SEO description for this article."
  })
});
const data = await response.json();
Response
201 Created
{
  "status": "created",
  "press_release": {
    "id": "1",
    "title": "My Article",
    "slug": "my-article"
  }
}
POST /api/press-releases/post Post a press release

Posts an existing press release to the press release widget on the home page. Paid members can post for 7 days at a cost of 70 credits (7 post points).

Parameters
Field Type Required Description
press_release_id integer Required ID of the press release to post. Must belong to the authenticated user.
days integer Optional Duration in days. Default is 7.
curl -X POST https://pagerankcafe.com/api/press-releases/post \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"press_release_id": 1, "days": 7}'
response = requests.post(
    "https://pagerankcafe.com/api/press-releases/post",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    },
    json={"press_release_id": 1, "days": 7}
)
data = response.json()
$payload = json_encode([
    'press_release_id' => 1,
    'days'             => 7
]);
$ch = curl_init("https://pagerankcafe.com/api/press-releases/post");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer YOUR_API_KEY',
    'Content-Type: application/json'
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch("https://pagerankcafe.com/api/press-releases/post", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ press_release_id: 1, days: 7 })
});
const data = await response.json();
Response
200 OK
{
  "status": "posted",
  "press_release_post": {
    "press_release_id": "1",
    "days": "7",
    "start_date": "2026-01-01 00:00:00",
    "end_date": "2026-01-08 00:00:00"
  }
}