curl -X GET "https://api.tktchurch.com/v1/livestreams?status=live&tag=sunday-service&start=2024-01-01T00:00:00Z"
const listLivestreams = async (params = {}) => {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(
`https://api.tktchurch.com/v1/livestreams?${queryString}`
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.reason || 'Failed to list livestreams');
}
return response.json();
};
// Usage
try {
const livestreams = await listLivestreams({
status: 'live',
tag: 'sunday-service',
start: '2024-01-01T00:00:00Z'
});
console.log('Livestreams:', livestreams);
} catch (error) {
console.error('Error:', error.message);
}
struct Livestream: Codable {
let id: UUID
let title: String
let description: String
let youtubeUrl: String?
let customStreamUrl: String?
let status: String
let scheduledStartTime: Date?
let actualStartTime: Date?
let endTime: Date?
let tags: [String]
let thumbnailUrl: String?
let thumbnail: ThumbnailInfo?
let createdByUserId: UUID
let updatedByUserId: UUID
let createdAt: Date?
let updatedAt: Date?
struct ThumbnailInfo: Codable {
let id: UUID?
let url: String
let provider: String
let key: String
}
}
struct PageResponse<T: Codable>: Codable {
let items: [T]
let metadata: PageMetadata
struct PageMetadata: Codable {
let page: Int
let per: Int
let total: Int
let pageCount: Int
}
}
func listLivestreams(
status: String? = nil,
tag: String? = nil,
start: Date? = nil
) async throws -> PageResponse<Livestream> {
var components = URLComponents(string: "https://api.tktchurch.com/v1/livestreams")!
var queryItems: [URLQueryItem] = []
if let status = status {
queryItems.append(URLQueryItem(name: "status", value: status))
}
if let tag = tag {
queryItems.append(URLQueryItem(name: "tag", value: tag))
}
if let start = start {
let formatter = ISO8601DateFormatter()
queryItems.append(URLQueryItem(name: "start", value: formatter.string(from: start)))
}
components.queryItems = queryItems
let (data, _) = try await URLSession.shared.data(from: components.url!)
return try JSONDecoder().decode(PageResponse<Livestream>.self, from: data)
}
// Usage
do {
let livestreams = try await listLivestreams(
status: "live",
tag: "sunday-service",
start: Date()
)
print("Livestreams:", livestreams)
} catch {
print("Error:", error)
}
data class Livestream(
val id: UUID,
val title: String,
val description: String,
val youtubeUrl: String?,
val customStreamUrl: String?,
val status: String,
val scheduledStartTime: String?,
val actualStartTime: String?,
val endTime: String?,
val tags: List<String>,
val thumbnailUrl: String?,
val thumbnail: ThumbnailInfo?,
val createdByUserId: UUID,
val updatedByUserId: UUID,
val createdAt: String?,
val updatedAt: String?
) {
data class ThumbnailInfo(
val id: UUID?,
val url: String,
val provider: String,
val key: String
)
}
data class PageResponse<T>(
val items: List<T>,
val metadata: PageMetadata
) {
data class PageMetadata(
val page: Int,
val per: Int,
val total: Int,
val pageCount: Int
)
}
suspend fun listLivestreams(
status: String? = null,
tag: String? = null,
start: String? = null
): PageResponse<Livestream> {
val url = buildString {
append("https://api.tktchurch.com/v1/livestreams")
val params = listOfNotNull(
status?.let { "status=$it" },
tag?.let { "tag=$it" },
start?.let { "start=$it" }
)
if (params.isNotEmpty()) {
append("?${params.joinToString("&")}")
}
}
return withContext(Dispatchers.IO) {
val request = Request.Builder()
.url(url)
.get()
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw IOException("Unexpected response ${response.code}")
}
val body = response.body?.string() ?: throw IOException("Empty response")
Json.decodeFromString<PageResponse<Livestream>>(body)
}
}
}
// Usage
try {
val livestreams = listLivestreams(
status = "live",
tag = "sunday-service",
start = "2024-01-01T00:00:00Z"
)
println("Livestreams: $livestreams")
} catch (e: Exception) {
println("Error: ${e.message}")
}
interface Thumbnail {
id?: string;
url: string;
provider: 's3' | 'local';
key: string;
}
interface Livestream {
id: string;
title: string;
description: string;
youtubeUrl?: string;
customStreamUrl?: string;
status: 'scheduled' | 'live' | 'ended' | 'cancelled';
scheduledStartTime?: string;
actualStartTime?: string;
endTime?: string;
tags: string[];
thumbnailUrl?: string;
thumbnail?: ThumbnailInfo?
createdByUserId: string;
updatedByUserId: string;
createdAt?: string;
updatedAt?: string;
}
interface PageMetadata {
page: number;
per: number;
total: number;
pageCount: number;
}
interface PageResponse<T> {
items: T[];
metadata: PageMetadata;
}
interface ListLivestreamsParams {
status?: string;
tag?: string;
start?: string;
page?: number;
per?: number;
}
const listLivestreams = async (params: ListLivestreamsParams = {}): Promise<PageResponse<Livestream>> => {
const queryString = new URLSearchParams(
Object.entries(params).filter(([_, value]) => value != null) as [string, string][]
).toString();
try {
const response = await axios.get<PageResponse<Livestream>>(
`https://api.tktchurch.com/v1/livestreams${queryString ? `?${queryString}` : ''}`
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.reason || 'Failed to list livestreams');
}
throw error;
}
};
// Usage
try {
const livestreams = await listLivestreams({
status: 'live',
tag: 'sunday-service',
start: '2024-01-01T00:00:00Z'
});
console.log('Livestreams:', livestreams);
} catch (error) {
console.error('Error:', error.message);
}
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Sunday Service",
"description": "Join us for our weekly Sunday service",
"youtubeUrl": "https://youtube.com/watch?v=abc123",
"customStreamUrl": null,
"status": "live",
"scheduledStartTime": "2024-01-21T10:00:00Z",
"actualStartTime": "2024-01-21T10:02:00Z",
"endTime": null,
"tags": ["sunday-service", "worship"],
"thumbnailUrl": "https://example.com/thumbnail.jpg",
"thumbnail": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"url": "https://storage.example.com/thumbnails/abc123.jpg",
"provider": "s3",
"key": "thumbnails/abc123.jpg"
},
"createdByUserId": "123e4567-e89b-12d3-a456-426614174002",
"updatedByUserId": "123e4567-e89b-12d3-a456-426614174002",
"createdAt": "2024-01-20T15:00:00Z",
"updatedAt": "2024-01-21T10:02:00Z"
}
],
"metadata": {
"page": 1,
"per": 10,
"total": 1,
"pageCount": 1
}
}
Livestreams
List Livestreams
List all livestreams with optional filtering
GET
/
livestreams
curl -X GET "https://api.tktchurch.com/v1/livestreams?status=live&tag=sunday-service&start=2024-01-01T00:00:00Z"
const listLivestreams = async (params = {}) => {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(
`https://api.tktchurch.com/v1/livestreams?${queryString}`
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.reason || 'Failed to list livestreams');
}
return response.json();
};
// Usage
try {
const livestreams = await listLivestreams({
status: 'live',
tag: 'sunday-service',
start: '2024-01-01T00:00:00Z'
});
console.log('Livestreams:', livestreams);
} catch (error) {
console.error('Error:', error.message);
}
struct Livestream: Codable {
let id: UUID
let title: String
let description: String
let youtubeUrl: String?
let customStreamUrl: String?
let status: String
let scheduledStartTime: Date?
let actualStartTime: Date?
let endTime: Date?
let tags: [String]
let thumbnailUrl: String?
let thumbnail: ThumbnailInfo?
let createdByUserId: UUID
let updatedByUserId: UUID
let createdAt: Date?
let updatedAt: Date?
struct ThumbnailInfo: Codable {
let id: UUID?
let url: String
let provider: String
let key: String
}
}
struct PageResponse<T: Codable>: Codable {
let items: [T]
let metadata: PageMetadata
struct PageMetadata: Codable {
let page: Int
let per: Int
let total: Int
let pageCount: Int
}
}
func listLivestreams(
status: String? = nil,
tag: String? = nil,
start: Date? = nil
) async throws -> PageResponse<Livestream> {
var components = URLComponents(string: "https://api.tktchurch.com/v1/livestreams")!
var queryItems: [URLQueryItem] = []
if let status = status {
queryItems.append(URLQueryItem(name: "status", value: status))
}
if let tag = tag {
queryItems.append(URLQueryItem(name: "tag", value: tag))
}
if let start = start {
let formatter = ISO8601DateFormatter()
queryItems.append(URLQueryItem(name: "start", value: formatter.string(from: start)))
}
components.queryItems = queryItems
let (data, _) = try await URLSession.shared.data(from: components.url!)
return try JSONDecoder().decode(PageResponse<Livestream>.self, from: data)
}
// Usage
do {
let livestreams = try await listLivestreams(
status: "live",
tag: "sunday-service",
start: Date()
)
print("Livestreams:", livestreams)
} catch {
print("Error:", error)
}
data class Livestream(
val id: UUID,
val title: String,
val description: String,
val youtubeUrl: String?,
val customStreamUrl: String?,
val status: String,
val scheduledStartTime: String?,
val actualStartTime: String?,
val endTime: String?,
val tags: List<String>,
val thumbnailUrl: String?,
val thumbnail: ThumbnailInfo?,
val createdByUserId: UUID,
val updatedByUserId: UUID,
val createdAt: String?,
val updatedAt: String?
) {
data class ThumbnailInfo(
val id: UUID?,
val url: String,
val provider: String,
val key: String
)
}
data class PageResponse<T>(
val items: List<T>,
val metadata: PageMetadata
) {
data class PageMetadata(
val page: Int,
val per: Int,
val total: Int,
val pageCount: Int
)
}
suspend fun listLivestreams(
status: String? = null,
tag: String? = null,
start: String? = null
): PageResponse<Livestream> {
val url = buildString {
append("https://api.tktchurch.com/v1/livestreams")
val params = listOfNotNull(
status?.let { "status=$it" },
tag?.let { "tag=$it" },
start?.let { "start=$it" }
)
if (params.isNotEmpty()) {
append("?${params.joinToString("&")}")
}
}
return withContext(Dispatchers.IO) {
val request = Request.Builder()
.url(url)
.get()
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw IOException("Unexpected response ${response.code}")
}
val body = response.body?.string() ?: throw IOException("Empty response")
Json.decodeFromString<PageResponse<Livestream>>(body)
}
}
}
// Usage
try {
val livestreams = listLivestreams(
status = "live",
tag = "sunday-service",
start = "2024-01-01T00:00:00Z"
)
println("Livestreams: $livestreams")
} catch (e: Exception) {
println("Error: ${e.message}")
}
interface Thumbnail {
id?: string;
url: string;
provider: 's3' | 'local';
key: string;
}
interface Livestream {
id: string;
title: string;
description: string;
youtubeUrl?: string;
customStreamUrl?: string;
status: 'scheduled' | 'live' | 'ended' | 'cancelled';
scheduledStartTime?: string;
actualStartTime?: string;
endTime?: string;
tags: string[];
thumbnailUrl?: string;
thumbnail?: ThumbnailInfo?
createdByUserId: string;
updatedByUserId: string;
createdAt?: string;
updatedAt?: string;
}
interface PageMetadata {
page: number;
per: number;
total: number;
pageCount: number;
}
interface PageResponse<T> {
items: T[];
metadata: PageMetadata;
}
interface ListLivestreamsParams {
status?: string;
tag?: string;
start?: string;
page?: number;
per?: number;
}
const listLivestreams = async (params: ListLivestreamsParams = {}): Promise<PageResponse<Livestream>> => {
const queryString = new URLSearchParams(
Object.entries(params).filter(([_, value]) => value != null) as [string, string][]
).toString();
try {
const response = await axios.get<PageResponse<Livestream>>(
`https://api.tktchurch.com/v1/livestreams${queryString ? `?${queryString}` : ''}`
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.reason || 'Failed to list livestreams');
}
throw error;
}
};
// Usage
try {
const livestreams = await listLivestreams({
status: 'live',
tag: 'sunday-service',
start: '2024-01-01T00:00:00Z'
});
console.log('Livestreams:', livestreams);
} catch (error) {
console.error('Error:', error.message);
}
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Sunday Service",
"description": "Join us for our weekly Sunday service",
"youtubeUrl": "https://youtube.com/watch?v=abc123",
"customStreamUrl": null,
"status": "live",
"scheduledStartTime": "2024-01-21T10:00:00Z",
"actualStartTime": "2024-01-21T10:02:00Z",
"endTime": null,
"tags": ["sunday-service", "worship"],
"thumbnailUrl": "https://example.com/thumbnail.jpg",
"thumbnail": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"url": "https://storage.example.com/thumbnails/abc123.jpg",
"provider": "s3",
"key": "thumbnails/abc123.jpg"
},
"createdByUserId": "123e4567-e89b-12d3-a456-426614174002",
"updatedByUserId": "123e4567-e89b-12d3-a456-426614174002",
"createdAt": "2024-01-20T15:00:00Z",
"updatedAt": "2024-01-21T10:02:00Z"
}
],
"metadata": {
"page": 1,
"per": 10,
"total": 1,
"pageCount": 1
}
}
Query Parameters
string
Filter by livestream status. One of:
scheduled: Upcoming livestreamlive: Currently streamingended: Completed livestreamcancelled: Cancelled livestream
string
Filter by tag
string
Filter by start date (ISO 8601 format)
string
Filter by end date (ISO 8601 format)
integer
Page number for pagination (default: 1)
integer
Items per page (default: 10)
Response
array
Array of livestream objects
Show Livestream Object
Show Livestream Object
string
Livestream’s unique identifier (UUID)
string
Title of the livestream
string
Description of the livestream
string
YouTube URL for the livestream
string
Custom streaming URL
string
Current status of the livestream (scheduled, live, ended, or cancelled)
string
Scheduled start time in ISO 8601 format
string
Actual start time in ISO 8601 format
string
End time in ISO 8601 format
array
Array of tags associated with the livestream
string
URL of the livestream thumbnail
object
string
UUID of the user who created the livestream
string
UUID of the user who last updated the livestream
string
Creation timestamp in ISO 8601 format
string
Last update timestamp in ISO 8601 format
object
curl -X GET "https://api.tktchurch.com/v1/livestreams?status=live&tag=sunday-service&start=2024-01-01T00:00:00Z"
const listLivestreams = async (params = {}) => {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(
`https://api.tktchurch.com/v1/livestreams?${queryString}`
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.reason || 'Failed to list livestreams');
}
return response.json();
};
// Usage
try {
const livestreams = await listLivestreams({
status: 'live',
tag: 'sunday-service',
start: '2024-01-01T00:00:00Z'
});
console.log('Livestreams:', livestreams);
} catch (error) {
console.error('Error:', error.message);
}
struct Livestream: Codable {
let id: UUID
let title: String
let description: String
let youtubeUrl: String?
let customStreamUrl: String?
let status: String
let scheduledStartTime: Date?
let actualStartTime: Date?
let endTime: Date?
let tags: [String]
let thumbnailUrl: String?
let thumbnail: ThumbnailInfo?
let createdByUserId: UUID
let updatedByUserId: UUID
let createdAt: Date?
let updatedAt: Date?
struct ThumbnailInfo: Codable {
let id: UUID?
let url: String
let provider: String
let key: String
}
}
struct PageResponse<T: Codable>: Codable {
let items: [T]
let metadata: PageMetadata
struct PageMetadata: Codable {
let page: Int
let per: Int
let total: Int
let pageCount: Int
}
}
func listLivestreams(
status: String? = nil,
tag: String? = nil,
start: Date? = nil
) async throws -> PageResponse<Livestream> {
var components = URLComponents(string: "https://api.tktchurch.com/v1/livestreams")!
var queryItems: [URLQueryItem] = []
if let status = status {
queryItems.append(URLQueryItem(name: "status", value: status))
}
if let tag = tag {
queryItems.append(URLQueryItem(name: "tag", value: tag))
}
if let start = start {
let formatter = ISO8601DateFormatter()
queryItems.append(URLQueryItem(name: "start", value: formatter.string(from: start)))
}
components.queryItems = queryItems
let (data, _) = try await URLSession.shared.data(from: components.url!)
return try JSONDecoder().decode(PageResponse<Livestream>.self, from: data)
}
// Usage
do {
let livestreams = try await listLivestreams(
status: "live",
tag: "sunday-service",
start: Date()
)
print("Livestreams:", livestreams)
} catch {
print("Error:", error)
}
data class Livestream(
val id: UUID,
val title: String,
val description: String,
val youtubeUrl: String?,
val customStreamUrl: String?,
val status: String,
val scheduledStartTime: String?,
val actualStartTime: String?,
val endTime: String?,
val tags: List<String>,
val thumbnailUrl: String?,
val thumbnail: ThumbnailInfo?,
val createdByUserId: UUID,
val updatedByUserId: UUID,
val createdAt: String?,
val updatedAt: String?
) {
data class ThumbnailInfo(
val id: UUID?,
val url: String,
val provider: String,
val key: String
)
}
data class PageResponse<T>(
val items: List<T>,
val metadata: PageMetadata
) {
data class PageMetadata(
val page: Int,
val per: Int,
val total: Int,
val pageCount: Int
)
}
suspend fun listLivestreams(
status: String? = null,
tag: String? = null,
start: String? = null
): PageResponse<Livestream> {
val url = buildString {
append("https://api.tktchurch.com/v1/livestreams")
val params = listOfNotNull(
status?.let { "status=$it" },
tag?.let { "tag=$it" },
start?.let { "start=$it" }
)
if (params.isNotEmpty()) {
append("?${params.joinToString("&")}")
}
}
return withContext(Dispatchers.IO) {
val request = Request.Builder()
.url(url)
.get()
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw IOException("Unexpected response ${response.code}")
}
val body = response.body?.string() ?: throw IOException("Empty response")
Json.decodeFromString<PageResponse<Livestream>>(body)
}
}
}
// Usage
try {
val livestreams = listLivestreams(
status = "live",
tag = "sunday-service",
start = "2024-01-01T00:00:00Z"
)
println("Livestreams: $livestreams")
} catch (e: Exception) {
println("Error: ${e.message}")
}
interface Thumbnail {
id?: string;
url: string;
provider: 's3' | 'local';
key: string;
}
interface Livestream {
id: string;
title: string;
description: string;
youtubeUrl?: string;
customStreamUrl?: string;
status: 'scheduled' | 'live' | 'ended' | 'cancelled';
scheduledStartTime?: string;
actualStartTime?: string;
endTime?: string;
tags: string[];
thumbnailUrl?: string;
thumbnail?: ThumbnailInfo?
createdByUserId: string;
updatedByUserId: string;
createdAt?: string;
updatedAt?: string;
}
interface PageMetadata {
page: number;
per: number;
total: number;
pageCount: number;
}
interface PageResponse<T> {
items: T[];
metadata: PageMetadata;
}
interface ListLivestreamsParams {
status?: string;
tag?: string;
start?: string;
page?: number;
per?: number;
}
const listLivestreams = async (params: ListLivestreamsParams = {}): Promise<PageResponse<Livestream>> => {
const queryString = new URLSearchParams(
Object.entries(params).filter(([_, value]) => value != null) as [string, string][]
).toString();
try {
const response = await axios.get<PageResponse<Livestream>>(
`https://api.tktchurch.com/v1/livestreams${queryString ? `?${queryString}` : ''}`
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.reason || 'Failed to list livestreams');
}
throw error;
}
};
// Usage
try {
const livestreams = await listLivestreams({
status: 'live',
tag: 'sunday-service',
start: '2024-01-01T00:00:00Z'
});
console.log('Livestreams:', livestreams);
} catch (error) {
console.error('Error:', error.message);
}
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Sunday Service",
"description": "Join us for our weekly Sunday service",
"youtubeUrl": "https://youtube.com/watch?v=abc123",
"customStreamUrl": null,
"status": "live",
"scheduledStartTime": "2024-01-21T10:00:00Z",
"actualStartTime": "2024-01-21T10:02:00Z",
"endTime": null,
"tags": ["sunday-service", "worship"],
"thumbnailUrl": "https://example.com/thumbnail.jpg",
"thumbnail": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"url": "https://storage.example.com/thumbnails/abc123.jpg",
"provider": "s3",
"key": "thumbnails/abc123.jpg"
},
"createdByUserId": "123e4567-e89b-12d3-a456-426614174002",
"updatedByUserId": "123e4567-e89b-12d3-a456-426614174002",
"createdAt": "2024-01-20T15:00:00Z",
"updatedAt": "2024-01-21T10:02:00Z"
}
],
"metadata": {
"page": 1,
"per": 10,
"total": 1,
"pageCount": 1
}
}
