Release Notes

Video Vault 1.0

Released October 24, 2026

Video Vault is the new home of the CMN video library API. It replaces the AchieveLab API with the same catalog of channels, speakers and videos and the same set of read-only endpoints, now kept in sync directly with Vimeo.

At a glance

Moving from AchieveLab

  1. Email admin@cmn.men to request your access token.
  2. Change your base URL to https://videovault.cmn.men/api.
  3. Send the token as a bearer token, and ask for JSON:
    Authorization: Bearer YOUR_TOKEN
    Accept: application/json
    
  4. Update your integration for the differences listed below, in particular GET /videos is now paginated.
  5. Test against the new API, then switch over.

Authentication

Every endpoint requires a bearer token. A request with a missing or invalid token returns 401:

{ "message": "Unauthenticated." }

Keep your token secret and store it server-side, not in browser or mobile app code. If you think a token has been exposed, tell admin@cmn.men right away so it can be replaced. Consumers can also ask for a second, reserve token, so a leaked token can be revoked and replaced without any downtime.

Endpoints

All endpoints use GET and return JSON with the results under a data key.

Endpoint Returns
/channels All channels
/channels/{id} One channel
/channels/{id}/videos Videos in a channel
/channels/{id}/speakers Speakers who appear in a channel's videos
/videos All videos, paginated
/videos/{id} One video, with its speakers and channels
/videos/{id}/channels Channels a video belongs to
/videos/{id}/speakers Speakers in a video
/speakers All speakers
/speakers/{id} One speaker
/speakers/{id}/videos Videos a speaker appears in
/speakers/{id}/channels Channels a speaker appears in

An unknown ID returns 404:

{ "message": "Not found." }

Pagination

GET /videos returns 100 videos per page. Choose a page with ?page=2. AchieveLab returned every video in a single response, so integrations that read only the first response will miss videos.

The response includes links and meta alongside data:

{
  "data": [ ... ],
  "links": {
    "first": "https://videovault.cmn.men/api/videos?page=1",
    "last": "https://videovault.cmn.men/api/videos?page=6",
    "prev": null,
    "next": "https://videovault.cmn.men/api/videos?page=2"
  },
  "meta": { "current_page": 1, "last_page": 6, "per_page": 100, "total": 573 }
}

Keep requesting links.next until it is null. A page number past the end returns an empty data list. All other list endpoints return their full results in one response.

Rate limits

Each consumer can make 100 requests per minute (AchieveLab allowed 60). Every response includes your limit and what remains:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97

Going over the limit returns 429 Too Many Requests with a Retry-After header giving the number of seconds to wait.

Changes that may affect your integration

Area AchieveLab Video Vault
Video id AchieveLab's video ID A new ID. The former AchieveLab ID is available as legacy_id.
Channel and speaker id Unchanged Unchanged
Video vimeo_id String, e.g. "240877013" Integer, e.g. 240877013
Date format 2017-11-08 07:49:22 ISO 8601 in UTC, e.g. 2017-11-08T07:49:22.000000Z
Video created_at / updated_at When the record was added or changed in AchieveLab When the video was created or last modified on Vimeo
Video title, length, image AchieveLab's stored values Taken from Vimeo, so wording and durations may differ slightly. image is a Vimeo-hosted thumbnail about 295 pixels wide.
pivot on nested speakers and channels Included Removed. It only repeated IDs already present.
GET /videos All videos in one response Paginated, 100 per page
Rate limit 60 per minute 100 per minute
Videos no longer on Vimeo Listed No longer listed

Matching your stored videos. If you saved AchieveLab video IDs, match them using legacy_id, or better, vimeo_id, which is stable. A small number of duplicate entries in the old catalog were consolidated into one video, so legacy_id can be null for those, and for any video added after launch.

New in Video Vault

These additions do not change existing fields.

Videos now also include:

Field Description
legacy_id The video's former AchieveLab ID, or null
description The description from Vimeo, or null
thumbnails Thumbnail images in several sizes, each with link, width and height
vimeo_link The video's page on Vimeo
player_url The Vimeo player URL for embedding
privacy The video's Vimeo view-privacy setting

Channels now also include image_url, the full address of the channel's image, or null if it has none. The existing image field still holds the image's file name, unchanged, so use image_url to display the image.

Speakers now include full_name, the first, middle and last names combined.

Kept in sync with Vimeo. Videos are managed in Vimeo, and the catalog is refreshed from it once a day. A change made in Vimeo, such as a new title, thumbnail or video, can take up to a day to appear in the API. The refresh schedule can be adjusted, so if you need updates to appear sooner, email admin@cmn.men.

Field reference

Video

Field Type
id integer
legacy_id integer or null
vimeo_id integer
title string
description string or null
length integer, seconds
image string or null, URL
thumbnails list of { link, width, height, link_with_play_button }
vimeo_link string, URL
player_url string, URL
privacy string
created_at, updated_at string, ISO 8601 UTC
speakers, channels lists (included by /videos and /videos/{id})

Channel: id, image (file name or null), image_url (full URL or null), name, slug, description, sort_order (integer or null), created_at, updated_at.

Speaker: id, first_name, middle_name (or null), last_name, full_name, created_at, updated_at.

Example

GET /api/videos/{id}, abridged:

{
  "data": {
    "id": 130,
    "legacy_id": 58,
    "vimeo_id": 240312902,
    "title": "Example Video",
    "description": null,
    "length": 1888,
    "image": "https://i.vimeocdn.com/video/...",
    "vimeo_link": "https://vimeo.com/240312902",
    "player_url": "https://player.vimeo.com/video/240312902",
    "privacy": "anybody",
    "created_at": "2017-10-28T20:30:28.000000Z",
    "updated_at": "2026-10-07T18:35:02.000000Z",
    "speakers": [ { "id": 1, "full_name": "Edwin Louis Cole", "...": "..." } ],
    "channels": [ { "id": 6, "name": "Dad Academy", "slug": "dad-academy", "...": "..." } ]
  }
}

Need help?

Email admin@cmn.men to request access, report a problem, or ask about moving your integration over.