curl -X GET "https://api.tktchurch.com/v1/newsletters/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const getNewsletter = async (accessToken, newsletterId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/newsletters/${newsletterId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.json();
};
// Usage
try {
const newsletter = await getNewsletter(
'eyJhbGciOiJIUzI1NiIs...',
'123e4567-e89b-12d3-a456-426614174000'
);
console.log('Newsletter:', newsletter);
} catch (error) {
console.error('Failed to get newsletter:', error.message);
}
func getNewsletter(accessToken: String, newsletterId: UUID) async throws -> Newsletter {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/newsletters/\(newsletterId)")!)
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw error
}
return try JSONDecoder().decode(Newsletter.self, from: data)
}
// Usage
do {
let newsletter = try await getNewsletter(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
newsletterId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("Newsletter:", newsletter)
} catch {
print("Failed to get newsletter:", error.localizedDescription)
}
class NewsletterService(private val client: OkHttpClient) {
suspend fun getNewsletter(accessToken: String, newsletterId: String): Newsletter {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/newsletters/$newsletterId")
.header("Authorization", "Bearer $accessToken")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
val error = response.body?.string()?.fromJson<ErrorResponse>()
throw Exception(error?.reason ?: "Failed to get newsletter")
}
return response.body?.string()?.fromJson<Newsletter>()
?: throw Exception("Empty response")
}
}
}
// Usage
try {
val newsletter = newsletterService.getNewsletter(
"eyJhbGciOiJIUzI1NiIs...",
"123e4567-e89b-12d3-a456-426614174000"
)
println("Newsletter: $newsletter")
} catch (e: Exception) {
println("Failed to get newsletter: ${e.message}")
}
import axios from 'axios';
interface Newsletter {
id: string;
title: string;
content: string;
image?: {
id: string;
url: string;
};
imageUrl?: string;
pdf?: {
id: string;
url: string;
};
pdfUrl?: string;
hasPdf: boolean;
status: 'draft' | 'scheduled' | 'published' | 'archived';
publishDate?: string;
recipientCount: number;
createdAt: string;
updatedAt: string;
createdBy: string;
}
const getNewsletter = async (
accessToken: string,
newsletterId: string
): Promise<Newsletter> => {
try {
const response = await axios.get(
`https://api.tktchurch.com/v1/newsletters/${newsletterId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to get newsletter');
}
throw error;
}
};
// Usage
try {
const newsletter = await getNewsletter(
'eyJhbGciOiJIUzI1NiIs...',
'123e4567-e89b-12d3-a456-426614174000'
);
console.log('Newsletter:', newsletter);
} catch (error) {
console.error('Failed to get newsletter:', error.message);
}
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "January Church Updates",
"content": "Welcome to our first newsletter of 2024...",
"image": {
"id": "file-123",
"url": "https://cdn.tktchurch.com/files/newsletter-image.jpg"
},
"imageUrl": null,
"pdf": {
"id": "file-456",
"url": "https://cdn.tktchurch.com/files/newsletter.pdf"
},
"pdfUrl": null,
"hasPdf": true,
"status": "published",
"publishDate": "2024-01-01T12:00:00Z",
"recipientCount": 150,
"createdAt": "2023-12-30T15:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z",
"createdBy": "user-123e4567-e89b-12d3-a456-426614174000"
}
{
"error": {
"status": 400,
"reason": "Invalid newsletter ID format"
}
}
{
"error": {
"status": 401,
"reason": "Invalid or expired access token"
}
}
{
"error": {
"status": 403,
"reason": "Missing required permission: readNewsletter"
}
}
{
"error": {
"status": 404,
"reason": "Newsletter not found"
}
}
Newsletters
Get Newsletter
Get details of a specific newsletter
GET
/
newsletters
/
{newsletterId}
curl -X GET "https://api.tktchurch.com/v1/newsletters/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const getNewsletter = async (accessToken, newsletterId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/newsletters/${newsletterId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.json();
};
// Usage
try {
const newsletter = await getNewsletter(
'eyJhbGciOiJIUzI1NiIs...',
'123e4567-e89b-12d3-a456-426614174000'
);
console.log('Newsletter:', newsletter);
} catch (error) {
console.error('Failed to get newsletter:', error.message);
}
func getNewsletter(accessToken: String, newsletterId: UUID) async throws -> Newsletter {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/newsletters/\(newsletterId)")!)
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw error
}
return try JSONDecoder().decode(Newsletter.self, from: data)
}
// Usage
do {
let newsletter = try await getNewsletter(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
newsletterId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("Newsletter:", newsletter)
} catch {
print("Failed to get newsletter:", error.localizedDescription)
}
class NewsletterService(private val client: OkHttpClient) {
suspend fun getNewsletter(accessToken: String, newsletterId: String): Newsletter {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/newsletters/$newsletterId")
.header("Authorization", "Bearer $accessToken")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
val error = response.body?.string()?.fromJson<ErrorResponse>()
throw Exception(error?.reason ?: "Failed to get newsletter")
}
return response.body?.string()?.fromJson<Newsletter>()
?: throw Exception("Empty response")
}
}
}
// Usage
try {
val newsletter = newsletterService.getNewsletter(
"eyJhbGciOiJIUzI1NiIs...",
"123e4567-e89b-12d3-a456-426614174000"
)
println("Newsletter: $newsletter")
} catch (e: Exception) {
println("Failed to get newsletter: ${e.message}")
}
import axios from 'axios';
interface Newsletter {
id: string;
title: string;
content: string;
image?: {
id: string;
url: string;
};
imageUrl?: string;
pdf?: {
id: string;
url: string;
};
pdfUrl?: string;
hasPdf: boolean;
status: 'draft' | 'scheduled' | 'published' | 'archived';
publishDate?: string;
recipientCount: number;
createdAt: string;
updatedAt: string;
createdBy: string;
}
const getNewsletter = async (
accessToken: string,
newsletterId: string
): Promise<Newsletter> => {
try {
const response = await axios.get(
`https://api.tktchurch.com/v1/newsletters/${newsletterId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to get newsletter');
}
throw error;
}
};
// Usage
try {
const newsletter = await getNewsletter(
'eyJhbGciOiJIUzI1NiIs...',
'123e4567-e89b-12d3-a456-426614174000'
);
console.log('Newsletter:', newsletter);
} catch (error) {
console.error('Failed to get newsletter:', error.message);
}
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "January Church Updates",
"content": "Welcome to our first newsletter of 2024...",
"image": {
"id": "file-123",
"url": "https://cdn.tktchurch.com/files/newsletter-image.jpg"
},
"imageUrl": null,
"pdf": {
"id": "file-456",
"url": "https://cdn.tktchurch.com/files/newsletter.pdf"
},
"pdfUrl": null,
"hasPdf": true,
"status": "published",
"publishDate": "2024-01-01T12:00:00Z",
"recipientCount": 150,
"createdAt": "2023-12-30T15:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z",
"createdBy": "user-123e4567-e89b-12d3-a456-426614174000"
}
{
"error": {
"status": 400,
"reason": "Invalid newsletter ID format"
}
}
{
"error": {
"status": 401,
"reason": "Invalid or expired access token"
}
}
{
"error": {
"status": 403,
"reason": "Missing required permission: readNewsletter"
}
}
{
"error": {
"status": 404,
"reason": "Newsletter not found"
}
}
This endpoint requires authentication and the
readNewsletter permission.Path Parameters
string
required
The UUID of the newsletter to retrieve
Response
string
Unique identifier for the newsletter (UUID)
string
Newsletter title
string
Newsletter content
string
External image URL if not using uploaded file
string
External PDF URL if not using uploaded file
boolean
Whether the newsletter has an associated PDF
string
Newsletter status. One of:
draft, scheduled, published, archivedstring
Scheduled or actual publication date (ISO 8601)
integer
Number of times the newsletter has been viewed/received
string
Creation timestamp (ISO 8601)
string
Last update timestamp (ISO 8601)
string
UUID of the user who created the newsletter
Error Responses
object
Common error cases:
- 400 Bad Request: Invalid newsletter ID format
- 401 Unauthorized: Missing or invalid access token
- 403 Forbidden: Missing required permission
- 404 Not Found: Newsletter not found
curl -X GET "https://api.tktchurch.com/v1/newsletters/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const getNewsletter = async (accessToken, newsletterId) => {
const response = await fetch(
`https://api.tktchurch.com/v1/newsletters/${newsletterId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.reason);
}
return response.json();
};
// Usage
try {
const newsletter = await getNewsletter(
'eyJhbGciOiJIUzI1NiIs...',
'123e4567-e89b-12d3-a456-426614174000'
);
console.log('Newsletter:', newsletter);
} catch (error) {
console.error('Failed to get newsletter:', error.message);
}
func getNewsletter(accessToken: String, newsletterId: UUID) async throws -> Newsletter {
var urlRequest = URLRequest(url: URL(string: "https://api.tktchurch.com/v1/newsletters/\(newsletterId)")!)
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, response) = try await URLSession.shared.data(for: urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
if httpResponse.statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw error
}
return try JSONDecoder().decode(Newsletter.self, from: data)
}
// Usage
do {
let newsletter = try await getNewsletter(
accessToken: "eyJhbGciOiJIUzI1NiIs...",
newsletterId: UUID(uuidString: "123e4567-e89b-12d3-a456-426614174000")!
)
print("Newsletter:", newsletter)
} catch {
print("Failed to get newsletter:", error.localizedDescription)
}
class NewsletterService(private val client: OkHttpClient) {
suspend fun getNewsletter(accessToken: String, newsletterId: String): Newsletter {
val request = Request.Builder()
.url("https://api.tktchurch.com/v1/newsletters/$newsletterId")
.header("Authorization", "Bearer $accessToken")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
val error = response.body?.string()?.fromJson<ErrorResponse>()
throw Exception(error?.reason ?: "Failed to get newsletter")
}
return response.body?.string()?.fromJson<Newsletter>()
?: throw Exception("Empty response")
}
}
}
// Usage
try {
val newsletter = newsletterService.getNewsletter(
"eyJhbGciOiJIUzI1NiIs...",
"123e4567-e89b-12d3-a456-426614174000"
)
println("Newsletter: $newsletter")
} catch (e: Exception) {
println("Failed to get newsletter: ${e.message}")
}
import axios from 'axios';
interface Newsletter {
id: string;
title: string;
content: string;
image?: {
id: string;
url: string;
};
imageUrl?: string;
pdf?: {
id: string;
url: string;
};
pdfUrl?: string;
hasPdf: boolean;
status: 'draft' | 'scheduled' | 'published' | 'archived';
publishDate?: string;
recipientCount: number;
createdAt: string;
updatedAt: string;
createdBy: string;
}
const getNewsletter = async (
accessToken: string,
newsletterId: string
): Promise<Newsletter> => {
try {
const response = await axios.get(
`https://api.tktchurch.com/v1/newsletters/${newsletterId}`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.error?.reason || 'Failed to get newsletter');
}
throw error;
}
};
// Usage
try {
const newsletter = await getNewsletter(
'eyJhbGciOiJIUzI1NiIs...',
'123e4567-e89b-12d3-a456-426614174000'
);
console.log('Newsletter:', newsletter);
} catch (error) {
console.error('Failed to get newsletter:', error.message);
}
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "January Church Updates",
"content": "Welcome to our first newsletter of 2024...",
"image": {
"id": "file-123",
"url": "https://cdn.tktchurch.com/files/newsletter-image.jpg"
},
"imageUrl": null,
"pdf": {
"id": "file-456",
"url": "https://cdn.tktchurch.com/files/newsletter.pdf"
},
"pdfUrl": null,
"hasPdf": true,
"status": "published",
"publishDate": "2024-01-01T12:00:00Z",
"recipientCount": 150,
"createdAt": "2023-12-30T15:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z",
"createdBy": "user-123e4567-e89b-12d3-a456-426614174000"
}
{
"error": {
"status": 400,
"reason": "Invalid newsletter ID format"
}
}
{
"error": {
"status": 401,
"reason": "Invalid or expired access token"
}
}
{
"error": {
"status": 403,
"reason": "Missing required permission: readNewsletter"
}
}
{
"error": {
"status": 404,
"reason": "Newsletter not found"
}
}
