Skip to content

Developer docs · v1

Radio Content Pro API reference

Everything you need to pull Radio Content Pro stories into your own site, app or CMS: authentication, every endpoint, every field and every error, with examples you can paste.

Version 1 · JSON over HTTPS · HTTP Basic auth

Overview

A small REST API over HTTPS

Three GET endpoints return the stories your subscription includes as JSON, plus their images. It’s the same API the Radio Content Pro WordPress plugin uses.
Base URL
https://app.radiocontentpro.com/wp-json/rcp/v1
The API at a glance
FormatJSON over HTTPS. Images come back as files.
AuthHTTP Basic: your account email and your API password.
MethodsGET only. The API reads; it never changes your account.
WindowPosts from the last 7 days.
Pages20 posts a page by default, up to 50.
Rate limitUp to 100 requests a minute per username.
ErrorsWordPress REST style: { code, message, data: { status } }.

Already using the API?

From November 9, 2026 it runs on the new Radio Content Pro platform. The base URL, your login and the response shape stay the same, so there’s nothing to change.

Quickstart

Your first request in three steps

  1. Get your API password.

    Email support@radiocontentpro.com from your account email. Your username is that email.

  2. Call GET /feed.

    With HTTP Basic auth, from your server.

  3. Publish what comes back.

    Each post has a headline, a blog post in HTML, an image and categories.

Your first request · cURL
curl -u you@station.com:YOUR_API_PASSWORD \
  'https://app.radiocontentpro.com/wp-json/rcp/v1/feed?per_page=5&fields=id,title,published,link,blog_post_title,blog_post_html,featured_image,categories'
Response · 200 OK
[
  {
    "id": 1000000000482,
    "title": "Surprise reunion tops the awards show",
    "published": "2026-11-09T11:00:00+00:00",
    "link": "https://app.radiocontentpro.com/app/story/48213",
    "blog_post_title": "A surprise reunion stole the awards show",
    "blog_post_html": "<p>The band hadn’t shared a stage in ten years. Last night they did.</p><p>Here’s what happened, and why fans can’t stop talking about it.</p>",
    "featured_image": {
      "url": "https://images.example.com/awards-reunion.jpg",
      "title": "Surprise reunion tops the awards show",
      "alt": "The band on stage at the awards show",
      "caption": "",
      "description": "",
      "width": 1200,
      "height": 800,
      "download_url": "https://app.radiocontentpro.com/wp-json/rcp/v1/media/1000000000482"
    },
    "categories": [
      {
        "id": 7,
        "slug": "pop-culture-news",
        "name": "Pop Culture News"
      }
    ]
  }
]

Authentication

HTTP Basic, with your account email

Send an Authorization header on every request. There are no tokens to fetch or refresh.
Credentials
UsernameYour Radio Content Pro account email. Sites set up before the new platform can keep the username they already use.
PasswordYour API password. It isn’t your sign-in password. Spaces in it are ignored, so a grouped paste works.

Get an API password

Email support@radiocontentpro.com from your account email and we’ll send one. Ask the same address to replace it if it leaks. Existing plugin and API logins carry over to the new platform; if yours stops working, email us for a new one.

The header
Authorization: Basic base64(you@station.com:YOUR_API_PASSWORD)

Keep it on your server

Your API password reads your subscription’s content. Call the API from your server or CMS, not from browser code: the API sends no CORS headers, so a browser on another site can’t call it anyway.

A missing or wrong credential gets a 401 with the code rest_auth. An account whose subscription includes no stories still authenticates: its feed is an empty list.

Endpoints

Endpoints

All under https://app.radiocontentpro.com/wp-json/rcp/v1.
Every endpoint
EndpointWhat it does
GET /feedList the posts your subscription includes, newest first.
GET /posts/{id}Get one post by its ID.
GET /media/{id}Download a post’s featured image.

GET/feed

The posts from the last 7 days in the categories your subscription includes, newest first. An account whose subscription includes none gets an empty list with a 200, never an error.

Endpoint
GET https://app.radiocontentpro.com/wp-json/rcp/v1/feed

Parameters

Parameters for GET /feed
NameInTypeDefaultDescription
per_pagequeryinteger20Posts per page, 1 to 50. Anything else is a 400.
pagequeryinteger1Which page. Past the last page you get an empty list.
afterquerystring (ISO 8601)—Only posts published after this time. Anything earlier than 7 days ago reads as 7 days ago, and a value that isn’t a date is ignored.
fieldsquerystringthe default setComma-separated field names, or all. Unknown names are skipped, not an error.

Response

200 OK. A JSON array of post objects (no wrapper object).

Response headers for GET /feed
HeaderMeaning
X-WP-TotalHow many posts match, across all pages.
X-WP-TotalPagesHow many pages that makes at this per_page.
Cache-Controlmax-age=300: the page can be reused for 5 minutes.

Errors

Errors for GET /feed
StatusCodeWhen
400rest_invalid_paramper_page isn’t a number from 1 to 50.
401rest_authThe Authorization header is missing, isn’t Basic, or the username and password don’t match.
429rate_limit_exceededToo many requests in one minute for the same username (the limit is up to 100). Wait for the next minute.

Example

GET /feed · cURL
curl -u you@station.com:YOUR_API_PASSWORD \
  'https://app.radiocontentpro.com/wp-json/rcp/v1/feed?per_page=5&fields=id,title,published,link,blog_post_title,blog_post_html,featured_image,categories'
Example response
[
  {
    "id": 1000000000482,
    "title": "Surprise reunion tops the awards show",
    "published": "2026-11-09T11:00:00+00:00",
    "link": "https://app.radiocontentpro.com/app/story/48213",
    "blog_post_title": "A surprise reunion stole the awards show",
    "blog_post_html": "<p>The band hadn’t shared a stage in ten years. Last night they did.</p><p>Here’s what happened, and why fans can’t stop talking about it.</p>",
    "featured_image": {
      "url": "https://images.example.com/awards-reunion.jpg",
      "title": "Surprise reunion tops the awards show",
      "alt": "The band on stage at the awards show",
      "caption": "",
      "description": "",
      "width": 1200,
      "height": 800,
      "download_url": "https://app.radiocontentpro.com/wp-json/rcp/v1/media/1000000000482"
    },
    "categories": [
      {
        "id": 7,
        "slug": "pop-culture-news",
        "name": "Pop Culture News"
      }
    ]
  }
]

GET/posts/{id}

One post object. A post older than 7 days is a 404, like a post that doesn’t exist.

Endpoint
GET https://app.radiocontentpro.com/wp-json/rcp/v1/posts/{id}

Parameters

Parameters for GET /posts/{id}
NameInTypeDefaultDescription
id (required)pathinteger—The post’s id, from the feed.
fieldsquerystringthe default setAs on /feed.

Response

200 OK. A JSON post object.

Response headers for GET /posts/{id}
HeaderMeaning
Cache-Controlmax-age=600: the post can be reused for 10 minutes.
Last-ModifiedWhen the post last changed.

Errors

Errors for GET /posts/{id}
StatusCodeWhen
401rest_authThe Authorization header is missing, isn’t Basic, or the username and password don’t match.
403forbiddenThe post exists but isn’t in a category your subscription includes.
404not_foundNo post has that ID, it’s older than 7 days, or the ID isn’t a positive whole number.
429rate_limit_exceededToo many requests in one minute for the same username (the limit is up to 100). Wait for the next minute.

Example

GET /posts/{id} · cURL
curl -u you@station.com:YOUR_API_PASSWORD \
  'https://app.radiocontentpro.com/wp-json/rcp/v1/posts/1000000000482?fields=id,title,blog_post_html'
Example response
{
  "id": 1000000000482,
  "title": "Surprise reunion tops the awards show",
  "blog_post_html": "<p>The band hadn’t shared a stage in ten years. Last night they did.</p><p>Here’s what happened, and why fans can’t stop talking about it.</p>"
}

GET/media/{id}

The image file itself, not JSON. You don’t build this URL: it’s featured_image.download_url on a post. Fetch it with the same credentials, from your server.

Endpoint
GET https://app.radiocontentpro.com/wp-json/rcp/v1/media/{id}

Parameters

Parameters for GET /media/{id}
NameInTypeDefaultDescription
id (required)pathinteger—The image’s id, the last part of featured_image.download_url.

Response

200 OK. The image bytes.

Response headers for GET /media/{id}
HeaderMeaning
Content-TypeThe image’s type, such as image/jpeg.
Content-Dispositionattachment, with the file name.

Errors

Errors for GET /media/{id}
StatusCodeWhen
401rest_authThe Authorization header is missing, isn’t Basic, or the username and password don’t match.
403forbiddenThe image belongs only to posts outside your subscription’s categories.
404not_foundNo post you can see uses that image, or the image can’t be fetched.
429rate_limit_exceededToo many requests in one minute for the same username (the limit is up to 100). Wait for the next minute.

Example

GET /media/{id} · cURL
curl -u you@station.com:YOUR_API_PASSWORD -o story.jpg \
  'https://app.radiocontentpro.com/wp-json/rcp/v1/media/1000000000482'

Reference

The post object

Every field a post can carry (65). Text is never null: a field a post doesn’t have is an empty string. Only featured_image and featured_image_html can be null.

The story

The story: fields
FieldTypeDescription
idDefaultintegerThe post’s ID. Use it with /posts/{id}, and to skip posts you already have.
slugstringA URL-friendly version of the title.
titleDefaultstringThe headline.
publishedDefaultstring (ISO 8601)When the post was published, with a UTC offset.
modifiedstring (ISO 8601)When the post last changed.
linkDefaultstring (URL)The story in Radio Content Pro.
excerptstringThe first 40 words of the post, as plain text.
content_htmlstring (HTML)The whole post.
content_textstringThe whole post as plain text.

The blog post

What the WordPress plugin publishes. Build on these.

The blog post: fields
FieldTypeDescription
blog_post_titleDefaultstringThe blog post’s headline.
blog_post_htmlDefaultstring (HTML)The blog post, ready to publish.
blog_post_textstringThe blog post as plain text.

Image and categories

Image and categories: fields
FieldTypeDescription
featured_imageDefaultobject or nullurl, title, alt, caption, description, width, height and download_url. download_url is /media/{id} on this API: fetch it with the same credentials. null when the post has no image.
featured_image_htmlDefaultstring (HTML) or nullA ready-made <img> tag. null when the post has no image.
categoriesDefaultarrayThe post’s categories, each { id, slug, name }.

On-air and social pieces

Kept so integrations built on them keep working. Many posts don’t carry them, and then they’re empty strings. Check before you use one.

On-air and social pieces: fields
FieldTypeDescription
tease_1Defaultstring (HTML)An on-air tease.
tease_1_textstringAn on-air tease. Plain text.
tease_2Defaultstring (HTML)A second tease.
tease_2_textstringA second tease. Plain text.
tease_3Defaultstring (HTML)A third tease.
tease_3_textstringA third tease. Plain text.
10_second_scriptDefaultstring (HTML)A 10-second read.
10_second_script_textstringA 10-second read. Plain text.
20_second_scriptDefaultstring (HTML)A 20-second read.
20_second_script_textstringA 20-second read. Plain text.
commentary_video_scriptDefaultstring (HTML)A video commentary script.
commentary_video_script_textstringA video commentary script. Plain text.
edgy_responseDefaultstring (HTML)An edgier take.
edgy_response_textstringAn edgier take. Plain text.
mainstream_responseDefaultstring (HTML)A mainstream take.
mainstream_response_textstringA mainstream take. Plain text.
family_friendly_responseDefaultstring (HTML)A family-friendly take.
family_friendly_response_textstringA family-friendly take. Plain text.
phone_topic_1Defaultstring (HTML)A caller topic.
phone_topic_1_textstringA caller topic. Plain text.
phone_topic_2Defaultstring (HTML)A second caller topic.
phone_topic_2_textstringA second caller topic. Plain text.
phone_topic_3Defaultstring (HTML)A third caller topic.
phone_topic_3_textstringA third caller topic. Plain text.
phone_topic_4Defaultstring (HTML)A fourth caller topic.
phone_topic_4_textstringA fourth caller topic. Plain text.
facebook_poststring (HTML)A Facebook post.
facebook_post_textstringA Facebook post. Plain text.
instagram_poststring (HTML)An Instagram caption.
instagram_post_textstringAn Instagram caption. Plain text.
x_post_edgystring (HTML)An X post, edgy.
x_post_edgy_textstringAn X post, edgy. Plain text.
x_post_mainstreamstring (HTML)An X post, mainstream.
x_post_mainstream_textstringAn X post, mainstream. Plain text.
x_post_family_friendlystring (HTML)An X post, family-friendly.
x_post_family_friendly_textstringAn X post, family-friendly. Plain text.
other_social_thought_starter_edgy_1string (HTML)A social prompt, edgy.
other_social_thought_starter_edgy_1_textstringA social prompt, edgy. Plain text.
other_social_thought_starter_edgy_2string (HTML)A second social prompt, edgy.
other_social_thought_starter_edgy_2_textstringA second social prompt, edgy. Plain text.
other_social_thought_starter_mainstream_1string (HTML)A social prompt, mainstream.
other_social_thought_starter_mainstream_1_textstringA social prompt, mainstream. Plain text.
other_social_thought_starter_mainstream_2string (HTML)A second social prompt, mainstream.
other_social_thought_starter_mainstream_2_textstringA second social prompt, mainstream. Plain text.
other_social_thought_starter_family_friendly_1string (HTML)A social prompt, family-friendly.
other_social_thought_starter_family_friendly_1_textstringA social prompt, family-friendly. Plain text.
other_social_thought_starter_family_friendly_2string (HTML)A second social prompt, family-friendly.
other_social_thought_starter_family_friendly_2_textstringA second social prompt, family-friendly. Plain text.
ai_image_generation_promptDefaultstringA description of an image for the story. Plain text.
ai_image_generation_prompt_textstringThe same, plain text.

Reference

Choosing fields

Add fields to /feed or /posts/{id} to get only what you use. Smaller responses, faster pages.
The fields parameter
RequestReturns
/feedThe default set. No fields parameter: the 23 most-used fields.
/feed?fields=allEvery field. all (or *) returns all 65.
/feed?fields=id,title,blog_post_html,featured_imageJust what a website needs. A list of names, comma-separated.

Names you misspell, or that don’t exist, are skipped without an error, so check your first response. The fields marked Default in the post object are the default set.

Reference

Pagination and new posts

The feed is newest first, 20 posts a page unless you set per_page (up to 50). The totals come back as headers.
Paging the feed
X-WP-TotalHow many posts match.
X-WP-TotalPagesHow many pages at your per_page. A page past the last returns [].
Read every page · JavaScript
// Read the whole 7-day window, page by page
async function allPosts(auth) {
  const posts = []
  for (let page = 1; ; page++) {
    const res = await fetch(`https://app.radiocontentpro.com/wp-json/rcp/v1/feed?per_page=50&page=${page}`, {
      headers: { Authorization: `Basic ${auth}` },
    })
    posts.push(...(await res.json()))
    if (page >= Number(res.headers.get('X-WP-TotalPages'))) return posts
  }
}

Only what’s new

Pass the time of your last check as after to get only posts published since. Keep the ids of posts you’ve already used, and skip them.

Posts since 6am UTC · cURL
curl -u you@station.com:YOUR_API_PASSWORD \
  'https://app.radiocontentpro.com/wp-json/rcp/v1/feed?after=2026-11-09T06:00:00Z'

Reference

Errors

Every error has the same JSON shape, with the HTTP status repeated inside it.
Error body
{
  "code": "rest_auth",
  "message": "Authentication required",
  "data": {
    "status": 401
  }
}
Every error the API returns
StatusCodeMessageWhen
400rest_invalid_paramInvalid parameter(s): per_pageper_page isn’t a number from 1 to 50.
401rest_authAuthentication requiredThe Authorization header is missing, isn’t Basic, or the username and password don’t match.
403forbiddenNot permitted to view this postThe post exists but isn’t in a category your subscription includes.
403forbiddenNot permitted to access this fileThe image belongs only to posts outside your subscription’s categories.
404not_foundPost not foundNo post has that ID, it’s older than 7 days, or the ID isn’t a positive whole number.
404not_foundMedia not foundNo post you can see uses that image, or the image can’t be fetched.
429rate_limit_exceededToo many requests. Please slow down.Too many requests in one minute for the same username (the limit is up to 100). Wait for the next minute.

Reference

Limits and caching

Limits
Rate limitUp to 100 requests a minute per username. Over it, you get a 429 until the next minute.
WindowThe last 7 days. Older posts leave the feed and /posts/{id} returns 404 for them, so keep your own copy of anything you publish.
Page sizeUp to 50 posts a request.
CachingA feed page can be reused for 5 minutes and a post for 10 (Cache-Control). Checking every few minutes is plenty.

Reference

Changelog

Version 1. Changes that affect integrations are listed here.
  1. The API moves to the new platform

    Same base URL, same login, same response shape. Integrations that already work need no changes.

On WordPress? The WordPress plugin uses this API for you, with no code. Questions about the API: support@radiocontentpro.com.

Ava Hart smiling, ready to help with your show

Ask Ava

Stuck on an endpoint? Ask me about this page.

Not a member yet?

The API is included with Radio Content Pro. Start your free trial, then email support for your API password.

No card needed · Cancel anytime