Skip to content

Error Codes

When an API request fails, Glyph returns a structured error response with details to help you diagnose and handle the issue.

All errors follow this structure:

{
"error": "Human-readable error message",
"code": "ERROR_CODE",
"details": { /* Additional context, if available */ }
}
FieldTypeDescription
errorstringHuman-readable error description
codestringMachine-readable error code
detailsobjectOptional additional context

Missing or invalid authentication.

{
"error": "Missing Authorization header",
"code": "HTTP_ERROR"
}

Possible causes:

  • No Authorization header provided
  • Invalid header format (should be Bearer <key>)
  • Invalid API key format (should start with gk_)
  • API key not found in database
  • API key revoked or deactivated

Solution: Verify your API key and header format.


Request body failed validation.

{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": [
{
"path": ["data", "client", "name"],
"message": "Required"
},
{
"path": ["data", "totals", "total"],
"message": "Expected number, received string"
}
]
}

Common validation issues:

  • Missing required fields
  • Wrong data types
  • Invalid email format
  • Empty arrays where items are required

Solution: Check the details array for specific field errors.


The modification prompt violated safety guardrails.

{
"error": "Invalid prompt",
"code": "GUARDRAIL_VIOLATION",
"details": {
"category": "unsafe_content"
}
}

Categories:

  • unsafe_content - Inappropriate or harmful content
  • injection_attempt - Detected prompt injection attempt
  • script_injection - Attempted to inject scripts

Solution: Rephrase your modification prompt.


Session not found.

{
"error": "Session not found",
"code": "HTTP_ERROR"
}

Possible causes:

  • Invalid session ID
  • Session belongs to a different API key
  • Session was deleted

Solution: Create a new session with /v1/preview.


Session has expired.

{
"error": "Session expired",
"code": "HTTP_ERROR"
}

Note: Sessions expire after 1 hour of inactivity.

Solution: Create a new session with /v1/preview.


RATE_LIMIT_EXCEEDED (429 Too Many Requests)

Section titled “RATE_LIMIT_EXCEEDED (429 Too Many Requests)”

Per-minute rate limit exceeded.

{
"error": "Rate limit exceeded",
"code": "RATE_LIMIT_EXCEEDED",
"retryAfter": 45,
"tier": "free",
"limit": 10,
"windowMs": 60000
}

Solution: Wait for retryAfter seconds, then retry.


MONTHLY_LIMIT_EXCEEDED (429 Too Many Requests)

Section titled “MONTHLY_LIMIT_EXCEEDED (429 Too Many Requests)”

Monthly PDF generation limit exceeded.

{
"error": "Monthly PDF limit exceeded",
"code": "MONTHLY_LIMIT_EXCEEDED",
"limit": 100,
"used": 100,
"tier": "free",
"upgrade": "https://glyph.you/pricing"
}

Solution: Wait until the next month or upgrade your plan.


Server configuration issue.

{
"error": "Session mode requires database configuration",
"code": "CONFIG_ERROR"
}

Note: This typically occurs on self-hosted deployments.

Solution: Ensure Supabase is properly configured.


PLAYWRIGHT_NOT_INSTALLED (503 Service Unavailable)

Section titled “PLAYWRIGHT_NOT_INSTALLED (503 Service Unavailable)”

PDF generation unavailable.

{
"error": "PDF generation not available. Playwright is not installed.",
"code": "PLAYWRIGHT_NOT_INSTALLED",
"details": {
"install": "bun add playwright && npx playwright install chromium"
}
}

Note: This occurs on self-hosted deployments without Playwright.

Solution: Install Playwright and Chromium.


GENERATE_ERROR (500 Internal Server Error)

Section titled “GENERATE_ERROR (500 Internal Server Error)”

PDF generation failed.

{
"error": "Failed to generate PDF",
"code": "GENERATE_ERROR"
}

Possible causes:

  • Invalid HTML content
  • Resource loading timeout
  • Server resource exhaustion

Solution: Verify your HTML is valid and try again.


Preview generation failed.

{
"error": "Template not found: invalid-template",
"code": "PREVIEW_ERROR"
}

Solution: Check template ID and data structure.


Modification failed.

{
"error": "AI service unavailable",
"code": "MODIFY_ERROR"
}

Solution: Retry the request. If persistent, contact support@glyph.you.


TEMPLATES_ERROR (500 Internal Server Error)

Section titled “TEMPLATES_ERROR (500 Internal Server Error)”

Failed to list templates.

{
"error": "Failed to load template registry",
"code": "TEMPLATES_ERROR"
}

Solution: This is a server-side issue. Contact support if persistent.


INTERNAL_ERROR (500 Internal Server Error)

Section titled “INTERNAL_ERROR (500 Internal Server Error)”

Unexpected server error.

{
"error": "Internal server error",
"code": "INTERNAL_ERROR"
}

Solution: Retry the request. If persistent, contact support.


Endpoint not found.

{
"error": "Not found",
"code": "NOT_FOUND",
"path": "/v1/invalid-endpoint"
}

Solution: Check the API endpoint path.


Requested template does not exist.

{
"error": "Template 'invalid-id' not found",
"code": "TEMPLATE_NOT_FOUND",
"details": {
"templateId": "invalid-id",
"availableTemplates": ["quote-modern", "invoice-clean", "..."]
}
}

Solution: Use GET /v1/templates to list available template IDs.


Generated document not found.

{
"error": "Document not found",
"code": "DOCUMENT_NOT_FOUND"
}

Solution: The document ID may be incorrect or the document was never created.


Generated document has expired.

{
"error": "Document has expired",
"code": "DOCUMENT_EXPIRED",
"expiredAt": "2026-01-28T12:00:00.000Z"
}

Solution: Regenerate the document. Configure a longer TTL using the ttl parameter in /v1/create.


Airtable token is invalid or expired.

{
"error": "Failed to connect to Airtable. Please check your API key.",
"code": "AIRTABLE_AUTH_ERROR"
}

Solution: Verify your Airtable Personal Access Token (PAT) is valid and has the required scopes.


Communication with Airtable API failed.

{
"error": "Failed to fetch records from Airtable.",
"code": "AIRTABLE_ERROR"
}

Solution: Check your Airtable API key, base ID, and table ID. The Airtable API may be temporarily unavailable.


Airtable key format is not recognized.

{
"error": "Invalid Airtable API key format. Keys should start with 'pat' (personal access token) or 'key' (legacy).",
"code": "INVALID_KEY_FORMAT"
}

Solution: Use a Personal Access Token from Airtable (starts with pat).


ANALYSIS_FAILED (500 Internal Server Error)

Section titled “ANALYSIS_FAILED (500 Internal Server Error)”

Data analysis failed during auto-detection.

{
"error": "Could not analyze data structure",
"code": "ANALYSIS_FAILED"
}

Solution: Ensure your data has recognizable fields (e.g., items, total, customer).


GENERATION_FAILED (500 Internal Server Error)

Section titled “GENERATION_FAILED (500 Internal Server Error)”

Document generation failed after analysis.

{
"error": "Failed to generate document",
"code": "GENERATION_FAILED"
}

Solution: Retry the request. If persistent, contact support.


Unexpected error during batch processing.

{
"error": "Unexpected error message",
"code": "BATCH_ERROR"
}

Individual item within a batch failed to generate.

{
"index": 2,
"status": "error",
"error": "Data object cannot be empty",
"errorCode": "ITEM_GENERATION_FAILED"
}

Note: This is not an HTTP error — it appears within the results array of a successful batch response. Other items in the batch continue processing.


Feature requires a registered API key.

{
"error": "Template persistence requires a registered API key. Please sign up to save templates.",
"code": "DEMO_TIER_LIMITATION"
}

Solution: Sign up for a free API key.


DATABASE_NOT_CONFIGURED (503 Service Unavailable)

Section titled “DATABASE_NOT_CONFIGURED (503 Service Unavailable)”

Feature requires database that is not configured.

{
"error": "Database is not configured",
"code": "DATABASE_NOT_CONFIGURED"
}

Note: This typically occurs on self-hosted deployments without Supabase.


Modification is impossible for the given document type.

{
"error": "This modification cannot be applied to a PDF document",
"code": "REQUEST_NOT_FEASIBLE"
}

AI attempted to remove document content, which was blocked by guardrails.

{
"error": "Modification blocked: would remove document content",
"code": "CONTENT_LOSS_BLOCKED"
}

Solution: Be more specific about what you want to change. Instead of “remove everything”, try “remove the footer section”.


StatusMeaningCommon Causes
400Bad RequestValidation error, guardrail violation
401UnauthorizedMissing or invalid API key
403ForbiddenDeactivated API key
404Not FoundInvalid endpoint or session
410GoneExpired session
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side error
503Service UnavailableConfiguration or dependency issue
async function callGlyph(endpoint, data) {
const response = await fetch(`https://api.glyph.you${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (!response.ok) {
const error = await response.json();
switch (error.code) {
case 'VALIDATION_ERROR':
console.error('Validation errors:', error.details);
throw new Error(`Invalid request: ${error.details.map(d => d.message).join(', ')}`);
case 'RATE_LIMIT_EXCEEDED':
console.log(`Rate limited. Retry in ${error.retryAfter}s`);
await sleep(error.retryAfter * 1000);
return callGlyph(endpoint, data); // Retry
case 'MONTHLY_LIMIT_EXCEEDED':
throw new Error('Monthly PDF limit reached. Please upgrade your plan.');
case 'GUARDRAIL_VIOLATION':
throw new Error('Your request was blocked for safety reasons.');
default:
throw new Error(error.error || 'Unknown error');
}
}
return response.json();
}