Skip to content

Error Handling

All API errors from the SDK throw a PromptlyError with a typed error code, HTTP status, and human-readable message.

import { PromptlyError } from '@promptlycms/prompts';
try {
const result = await promptly.getPrompt('nonexistent');
} catch (err) {
if (err instanceof PromptlyError) {
console.error(err.code); // 'NOT_FOUND'
console.error(err.status); // 404
console.error(err.message); // 'Prompt not found'
}
}
PropertyTypeDescription
codeErrorCodeMachine-readable error code
statusnumberHTTP status code from the API
messagestringHuman-readable error description
usageunknownUsage data (present on 429 responses)
upgradeUrlstringUpgrade link (present on 429 responses)
CodeHTTP StatusDescription
UNAUTHORIZED401Missing or empty API key
INVALID_KEY401API key is invalid or revoked
NOT_FOUND404Prompt ID does not exist
VERSION_NOT_FOUND404Requested version does not exist
BAD_REQUEST400Invalid request (e.g. malformed prompt ID)
USAGE_LIMIT_EXCEEDED429Rate limit or usage quota exceeded

When you hit a rate limit (429), the error includes usage data and an upgrade link:

try {
await promptly.getPrompt('my-prompt');
} catch (err) {
if (err instanceof PromptlyError && err.code === 'USAGE_LIMIT_EXCEEDED') {
console.log('Current usage:', err.usage);
console.log('Upgrade at:', err.upgradeUrl);
}
}

The SDK also throws PromptlyError for client-side validation issues:

import { createPromptlyClient } from '@promptlycms/prompts';
// Throws PromptlyError with code 'UNAUTHORIZED'
// if PROMPTLY_API_KEY is not set and no apiKey is passed
const promptly = createPromptlyClient();
// Throws PromptlyError with code 'BAD_REQUEST'
// if the model's provider package isn't installed
const result = await promptly.getPrompt('uses-claude-model');
import { PromptlyError } from '@promptlycms/prompts';
const fetchPrompt = async (promptId: string) => {
try {
return await promptly.getPrompt(promptId);
} catch (err) {
if (!(err instanceof PromptlyError)) {
throw err;
}
if (err.code === 'NOT_FOUND') {
return null;
}
if (err.code === 'USAGE_LIMIT_EXCEEDED') {
console.warn('Rate limited, retrying after delay...');
await new Promise((r) => setTimeout(r, 1000));
return promptly.getPrompt(promptId);
}
throw err;
}
};