md-platform

client-slug-resolve.md
View raw Back to list

Slug Resolve Endpoint

Resolves a URL slug to an entity (Channel, Content, or Video) and returns its data.

Endpoint

GET /client/v1/slugs/{slug}
GET /mobile/v1/slugs/{slug}

Usage in Next.js

In your catch-all route app/[...slug]/page.tsx, take the full path and pass it to the endpoint:

// app/[...slug]/page.tsx
const fullSlug = params.slug.join("/");
const res = await fetch(`${API_URL}/client/v1/slugs/${fullSlug}`);
const { entityType, data } = await res.json();

Slug Parsing Rules

The API parses nested slugs automatically. It takes the last non-reserved segment from the path.

Reserved keywords (ignored during resolution):

URL Path Resolved Slug
/rrushe rrushe
/rrushe/rrushe-sezoni-1 rrushe-sezoni-1
/rrushe/sezoni-2 rrushe
/rrushe/per-shfaqjen rrushe
/rrushe/rrushe-sezoni-1/per-shfaqjen rrushe-sezoni-1

Response

{
  "entityType": 1,
  "data": { ... }
}

Entity Types

Value Type
1 Channel
2 Content
3 Video

Response per Entity Type

Channel (entityType: 1)

{
  "entityType": 1,
  "data": {
    "id": "abc123",
    "name": "Channel Name",
    "handle": "channel-handle",
    "about": "...",
    "image": "...",
    "banner": "...",
    "mobileBanner": "...",
    "link": "/channel-handle",
    "status": 1,
    "metrics": { "subscribers": 100, "videos": 50 },
    "isPremium": false,
    "payToViewConfig": null
  }
}

Content (entityType: 2)

{
  "entityType": 2,
  "data": {
    "id": "xyz789",
    "title": "Movie Title",
    "description": "...",
    "handle": "movie-title",
    "type": 1,
    "releaseDate": "2026-01-15T00:00:00",
    "thumbnail": "...",
    "banner": "...",
    "landscapeBanner": "...",
    "mobileBanner": "...",
    "videos": [
      {
        "videoId": "vid123",
        "type": 1,
        "name": "Main Video",
        "thumbnail": "..."
      }
    ]
  }
}

Content type values: 1 = Movie, 2 = Series, 3 = Season, 5 = Match, 6 = Playlist

Video (entityType: 3)

{
  "entityType": 3,
  "data": {
    "id": "vid123",
    "name": "Video Title",
    "shortDescription": "...",
    "thumbnail": "...",
    "duration": 3600,
    "type": 0,
    "status": 0,
    "channel": {
      "id": "abc123",
      "name": "Channel Name",
      "handle": "channel-handle",
      "image": "..."
    },
    "metrics": { "views": 1000, "likes": 50 },
    "playerConfig": { ... }
  }
}

Error Responses

404 - Slug not found

{
  "message": "Slug 'unknown-slug' not found",
  "entity": "slug"
}

Front-end Example

// app/[...slug]/page.tsx
import { notFound } from "next/navigation";

enum EntityType {
  Channel = 1,
  Content = 2,
  Video = 3,
}

export default async function SlugPage({ params }: { params: { slug: string[] } }) {
  const fullSlug = params.slug.join("/");
  const res = await fetch(`${process.env.API_URL}/client/v1/slugs/${fullSlug}`);

  if (!res.ok) return notFound();

  const { entityType, data } = await res.json();

  switch (entityType) {
    case EntityType.Channel:
      return <ChannelPage channel={data} />;
    case EntityType.Content:
      return <ContentPage content={data} />;
    case EntityType.Video:
      return <VideoPage video={data} />;
    default:
      return notFound();
  }
}