Errors
Error response format and status codes for the Wrytze API.
The Wrytze API uses conventional HTTP status codes and a consistent error response format to indicate when something goes wrong. Every error response contains an error object with a human-readable message and the HTTP status code.
Error Format
All error responses follow this structure:
{
"error": {
"message": "Human-readable error description",
"status": 400
}
}The message field provides a description of what went wrong. The status field mirrors the HTTP status code of the response.
Error Codes
| Status | Name | Description | Common Causes |
|---|---|---|---|
400 | Bad Request | Invalid request parameters | limit exceeds 100, invalid query parameters, malformed request |
401 | Unauthorized | Authentication failed | Missing X-API-Key header, invalid API key, expired API key |
403 | Forbidden | Access denied | API key belongs to a different organization, insufficient permissions |
404 | Not Found | Resource not found | Blog does not exist, blog is not published, resource belongs to a different organization |
429 | Rate Limited | Too many requests | Exceeded 100 requests per minute per API key |
500 | Server Error | Internal server error | Unexpected server-side issue |
Error Examples
400 Bad Request
Returned when the request contains invalid parameters.
{
"error": {
"message": "Invalid limit parameter. Must be between 1 and 100.",
"status": 400
}
}{
"error": {
"message": "Blog slug is required",
"status": 400
}
}How to fix: Check the request parameters against the API reference. Ensure numeric parameters are valid integers and string parameters are non-empty.
401 Unauthorized
Returned when the API key is missing, invalid, or expired.
{
"error": {
"message": "Invalid or missing API key. Provide a valid key in the X-API-Key header.",
"status": 401
}
}{
"error": {
"message": "Invalid or missing API key. Provide a valid key in the X-API-Key header.",
"status": 401
}
}How to fix:
- Verify that you are including the
X-API-Keyheader in your request - Confirm the API key is correct and has not been revoked
- Check if the API key has expired in the Wrytze dashboard
- Ensure you are using the full API key value (not the truncated version shown in the dashboard)
403 Forbidden
Returned when the API key is valid but does not have access to the requested resource.
{
"error": {
"message": "Access denied",
"status": 403
}
}How to fix:
- Verify that the API key belongs to the organization that owns the requested resource
- API keys are scoped to a single organization and cannot access data from other organizations
404 Not Found
Returned when the requested resource does not exist or is not accessible.
{
"error": {
"message": "Blog not found",
"status": 404
}
}{
"error": {
"message": "Website not found in your organization",
"status": 404
}
}How to fix:
- Verify the resource ID or slug is correct
- Confirm the blog has been published (draft and scheduled posts are not available via the API)
- Check that the
website_idparameter matches a website in your organization - Ensure the resource has not been deleted
429 Rate Limited
Returned when you have exceeded the rate limit of 100 requests per minute.
{
"error": {
"message": "Rate limit exceeded",
"status": 429
}
}The response includes additional headers:
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1708920000000
Retry-After: 34How to fix: Wait for the number of seconds specified in the Retry-After header before retrying. See the Rate Limits page for best practices on handling rate limits.
500 Server Error
Returned when an unexpected error occurs on the server.
{
"error": {
"message": "Internal server error",
"status": 500
}
}How to fix:
- Retry the request after a short delay
- If the error persists, contact support with the request details (endpoint, parameters, timestamp)
- Do not include your API key when reporting issues
Error Handling Example
Here is a complete example of how to handle errors from the Wrytze API:
interface WrytzeError {
error: {
message: string;
status: number;
};
}
async function fetchBlog(id: string, apiKey: string) {
const response = await fetch(
`https://app.wrytze.com/api/v1/blogs/${id}`,
{ headers: { "X-API-Key": apiKey } }
);
if (!response.ok) {
const body: WrytzeError = await response.json();
switch (response.status) {
case 401:
throw new Error("Invalid API key. Check your credentials.");
case 404:
throw new Error(`Blog "${id}" not found or not published.`);
case 429: {
const retryAfter = response.headers.get("Retry-After");
throw new Error(
`Rate limited. Retry after ${retryAfter} seconds.`
);
}
default:
throw new Error(
`API error (${body.error.status}): ${body.error.message}`
);
}
}
const { data } = await response.json();
return data;
}async function fetchBlog(id, apiKey) {
const response = await fetch(
`https://app.wrytze.com/api/v1/blogs/${id}`,
{ headers: { "X-API-Key": apiKey } }
);
if (!response.ok) {
const body = await response.json();
switch (response.status) {
case 401:
throw new Error("Invalid API key. Check your credentials.");
case 404:
throw new Error(`Blog "${id}" not found or not published.`);
case 429: {
const retryAfter = response.headers.get("Retry-After");
throw new Error(
`Rate limited. Retry after ${retryAfter} seconds.`
);
}
default:
throw new Error(
`API error (${body.error.status}): ${body.error.message}`
);
}
}
const { data } = await response.json();
return data;
}The TypeScript SDK handles error parsing automatically and throws typed exceptions for each error code, so you do not need to write this boilerplate yourself.