Skoolyst Ads

Skoolyst Ads is the centralized advertising engine for the Skoolyst ecosystem. Advertisers submit ads, an admin reviews them, and any connected Skoolyst application can request and display approved ads for its own placements through one shared API.

Available — v1

Website: ads.skoolyst.com. Unlike most other Skoolyst products in this documentation, Ads is not a planning-stage module — it is a deployed, working application with its own database, advertiser dashboard, admin panel and public API, currently on its first tracked release (v1). Future changes to it will be documented as bug fixes, modifications and updates in the Release Notes.

Overview

Every Skoolyst application could build its own ad-management system, but that would mean repeating the same advertiser dashboard, moderation workflow and ad-serving logic in every app. Skoolyst Ads exists so this only has to be built once: it is a separate application that any Skoolyst property can connect to, so all of them share one advertising infrastructure instead of maintaining separate ones.

Three kinds of participants use it:

How it works, end to end

  1. An admin registers a connected app in Admin → Connected Apps, which generates an API key for that app.
  2. The admin defines that app's placements — the named slots an ad can be shown in, for example header, footer or sidebar. Every connected app defines its own set of placements independently.
  3. An advertiser creates an ad: they pick the target app, choose which of that app's placements it should run on, and provide the ad's content and an optional schedule.
  4. The ad starts in Pending status. An admin reviews it and either approves it (making it Active) or rejects it.
  5. The connected app calls the Ads API, asking "what ad should I show for placement X?" Skoolyst Ads returns one eligible active ad for that app and placement, or nothing if none qualifies.
  6. The connected app displays the ad and is responsible for reporting clicks and impressions back so the advertiser and admin can see performance.

Connected apps, API keys and placements

An advertiser can only target apps that an admin has already connected. Each connected app has:

A placement can only be deleted once no ad is still linked to it — this is a deliberate safeguard, since placements and ads are connected at the database level and removing an in-use placement would otherwise take its ads down with it.

Creating an advertisement

An advertiser submits an ad with the following:

FieldDescription
Advertiser nameThe name shown as the ad's sender/sponsor.
Title & descriptionThe ad's headline and supporting text.
ImageThe ad creative shown alongside the text.
Call-to-action textThe button/link label, for example "Book Now" or "Learn More".
Click URLWhere a click on the ad should lead.
Target appWhich connected app this ad should run on.
Placement(s)One, several, or all of the target app's placements — see below.
Start / end dateOptional schedule window. Left blank, an approved ad runs with no date restriction.

Once created, an ad's target app and placement selection are fixed — they cannot be changed afterward. Everything else (title, description, image, CTA, click URL, schedule) can still be edited, which resets the ad back to Pending for re-review.

Targeting more than one placement

An ad is not limited to a single placement. If a connected app defines several placements — for example header, footer and sidebar — an advertiser can select any one of them, several, or all of them for the same ad, and it will run on every placement selected. This is handled by linking the ad to each chosen placement individually, rather than the ad only ever being able to point at one slot.

Moderation and ad status

Every ad moves through a status lifecycle that both the advertiser and the admin can see:

StatusMeaning
pendingSubmitted (or just edited) and waiting for admin review. Not yet servable.
activeApproved and within its schedule window — eligible to be returned by the API.
pausedTemporarily stopped by an admin or advertiser without losing the ad's history.
rejectedReviewed and declined by an admin, with a reason recorded.
endedPast its scheduled end date.
deletedRemoved by the advertiser or an admin. Kept as a soft delete rather than erased outright, so moderation history is preserved.

Every moderation action an admin takes — approving, rejecting, pausing, reactivating, regenerating an app's API key, or changing a connected app's or placement's setup — is written to an audit log, so there is a record of who did what and when.

Click and impression tracking

Skoolyst Ads records impressions (how often an ad was shown) and clicks (how often it was clicked) per day, per ad. Advertisers can see these numbers for their own ads, and the admin can see totals across every ad, to understand which ads are performing well.

The Ads API

Connected apps fetch ads through one public endpoint. Full request/response reference:

# Get an ad for a placement

## Description
Returns one eligible ad for the requesting app's given placement, or
null if nothing currently qualifies (no approved ad targets that
placement, the app is paused, or nothing is within its schedule
window).

## Request
- Method: GET
- URL: /api/v1/ads/serve
- Headers: Authorization: Bearer <connected-app-api-key>
- Query: placement=<placement-code>

## Response
Status: 200 OK
Content-Type: application/json

{
  "success": true,
  "data": {
    "ad": {
      "id": 1,
      "title": "Speak Confidently in 8 Weeks",
      "description": "Small group classes",
      "image_path": "/uploads/ads/example.jpg",
      "cta_text": "Book Now",
      "click_url": "https://example.com/enroll"
    }
  }
}

If nothing is eligible, "ad" is null rather than the request failing.

## Errors
| Status | Description                              |
|--------|-------------------------------------------|
| 401    | Missing or invalid API key                |
| 404    | Unknown app or placement code             |

Each connected app authenticates with its own API key rather than a shared one, so one app's key can be revoked or regenerated without affecting any other app's integration.

Version 1

What is documented on this page is Skoolyst Ads' first tracked release. It includes:

See Versions for how this fits alongside the rest of the Skoolyst ecosystem, and Release Notes for the dated v1 entry. From here on, changes to Skoolyst Ads are tracked as bug fixes, modifications and updates against this baseline rather than as a from-scratch build.