Thanks so much for testing this, Cathy.
I’m using "@tryghost/admin-api": "^1.13.12",
so same as yours.
I logged out all the values and everything seems ok. It should work.
Putting the wrong key gives me a different error.
For completeness, here’s my full nextjs test route:
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import GhostAdminAPI from '@tryghost/admin-api'
const subscribeRequestSchema = z.object({
email: z.string().email(),
source: z.string(),
})
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const { email, source } = subscribeRequestSchema.parse(body)
const ghostApiUrl = process.env.GHOST_ADMIN_API_URL
const ghostAdminApiKey = process.env.GHOST_ADMIN_API_KEY
if (!ghostApiUrl || !ghostAdminApiKey) {
throw new Error('Ghost API configuration missing')
}
console.log('Ghost API URL:', ghostApiUrl)
console.log('Ghost Admin Key format check:', {
hasColon: ghostAdminApiKey.includes(':'),
length: ghostAdminApiKey.length,
prefix: ghostAdminApiKey.substring(0, 6) + '...'
})
const api = new GhostAdminAPI({
url: ghostApiUrl,
key: ghostAdminApiKey,
version: 'v5.0'
})
try {
console.log('Attempting to add member:', { email, source })
console.log("ghostApiUrl", ghostApiUrl)
console.log("ghostAdminApiKey", ghostAdminApiKey)
console.log("email", email)
console.log("source", source)
await api.members.add({
email,
labels: [`source:${source}`]
}, {
send_email: false // Don't send welcome email
})
return NextResponse.json({ success: true })
} catch (error: any) {
console.error('Detailed Ghost API error:', {
message: error.message,
context: error.context,
type: error.type,
details: error.details,
stack: error.stack
})
if (error.message?.includes('Member already exists')) {
return NextResponse.json({ success: true })
}
return NextResponse.json(
{
message: 'Failed to subscribe',
details: error.context || error.message
},
{ status: 500 }
)
}
} catch (error) {
console.error('Subscription error:', error)
if (error instanceof z.ZodError) {
return NextResponse.json(
{ message: 'Invalid request data' },
{ status: 400 }
)
}
return NextResponse.json(
{ message: 'Internal server error' },
{ status: 500 }
)
}
}
This makes me think it might actually be a permissions problem on a lower level.
I’ve had this instance for years now and it’s gone through many version updates so far.
What do permission look like for you in the database? Maybe I need to fiddle with it.