📋 Overview
The NVLP API uses standard HTTP status codes and provides detailed error messages to help you identify and resolve issues quickly. This reference covers all possible error scenarios you might encounter.
🔍 Error Response Format
All error responses follow a consistent JSON format:
{
"error": "Brief error description",
"details": "Detailed explanation (optional)",
"code": "NVLP_ERROR_CODE (optional)",
"field": "field_name (for validation errors)"
}
🚦 HTTP Status Codes
NVLP API uses standard HTTP status codes to indicate the success or failure of requests:
Status Code | Meaning | When It Occurs |
---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
204 | No Content | Request succeeded, no response body |
400 | Bad Request | Invalid request format or missing required fields |
401 | Unauthorized | Missing, invalid, or expired authentication token |
403 | Forbidden | Valid authentication but insufficient permissions |
404 | Not Found | Resource doesn't exist or user doesn't have access |
409 | Conflict | Request conflicts with current resource state |
422 | Unprocessable Entity | Valid request format but business logic validation failed |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Unexpected server error |
🔐 Authentication Errors
Error | Status | Description | Solution |
---|---|---|---|
MISSING_AUTH_HEADER |
401 | No Authorization header provided | Include Authorization: Bearer TOKEN header |
INVALID_TOKEN_FORMAT |
401 | Authorization header format is incorrect | Use format: Authorization: Bearer YOUR_TOKEN |
TOKEN_EXPIRED |
401 | JWT token has expired | Request new magic link or refresh token |
INVALID_TOKEN |
401 | Token signature is invalid or corrupted | Request new magic link authentication |
USER_NOT_FOUND |
401 | User associated with token doesn't exist | Re-authenticate with magic link |
MAGIC_LINK_EXPIRED |
400 | Magic link has expired (typically after 1 hour) | Request a new magic link |
MAGIC_LINK_USED |
400 | Magic link has already been used | Request a new magic link |
RATE_LIMIT_MAGIC_LINK |
429 | Too many magic link requests for this email | Wait before requesting another magic link |
🔧 Quick Fix for Auth Errors
// Check token expiration
function isTokenExpired(token) {
try {
const payload = JSON.parse(atob(token.split('.')[1]));
const currentTime = Math.floor(Date.now() / 1000);
return payload.exp < currentTime;
} catch {
return true;
}
}
// Handle 401 responses
if (response.status === 401) {
localStorage.removeItem('nvlp_access_token');
window.location.href = '/login';
}
✅ Validation Errors
These errors occur when request data doesn't meet the API's validation requirements:
Error | Status | Description | Example |
---|---|---|---|
REQUIRED_FIELD_MISSING |
400 | Required field is missing from request | {"error": "Name is required", "field": "name"} |
INVALID_EMAIL_FORMAT |
400 | Email address format is invalid | {"error": "Invalid email format", "field": "email"} |
INVALID_AMOUNT |
400 | Amount must be positive number | {"error": "Amount must be greater than 0", "field": "amount"} |
INVALID_DATE_FORMAT |
400 | Date format is invalid | {"error": "Date must be YYYY-MM-DD format", "field": "transaction_date"} |
INVALID_UUID |
400 | UUID format is invalid | {"error": "Invalid UUID format", "field": "budget_id"} |
STRING_TOO_LONG |
400 | String exceeds maximum length | {"error": "Name too long (max 255 chars)", "field": "name"} |
INVALID_ENUM_VALUE |
400 | Value not in allowed enum options | {"error": "Invalid transaction type", "field": "transaction_type"} |
💼 Business Logic Errors
These errors occur when requests are valid but violate business rules:
Error | Status | Description | Solution |
---|---|---|---|
INSUFFICIENT_BALANCE |
422 | Envelope doesn't have enough balance for transaction | Check envelope balance or allocate more funds |
INVALID_TRANSACTION_FIELDS |
422 | Transaction type and required fields don't match | Review transaction type requirements |
CANNOT_DELETE_WITH_BALANCE |
409 | Cannot delete envelope with non-zero balance | Transfer funds out or zero the balance first |
CANNOT_TRANSFER_SAME_ENVELOPE |
422 | Cannot transfer from envelope to itself | Choose different source and destination envelopes |
BUDGET_ACCESS_DENIED |
403 | User doesn't have access to this budget | Verify budget ownership or permissions |
RESOURCE_NOT_FOUND |
404 | Referenced resource doesn't exist | Verify resource ID exists and user has access |
DUPLICATE_NAME |
409 | Resource name already exists in budget | Choose a different name |
CANNOT_RESTORE_TRANSACTION |
409 | Transaction cannot be restored due to balance constraints | Ensure sufficient balance for restoration |
⚠️ Transaction Validation Rules
Different transaction types require specific fields:
- INCOME: Requires
income_source_id
only - ALLOCATION: Requires
to_envelope_id
only - EXPENSE/DEBT_PAYMENT: Requires
from_envelope_id
+payee_id
- TRANSFER: Requires
from_envelope_id
+to_envelope_id
(different)
🚦 Rate Limiting
NVLP implements rate limiting to ensure fair usage and prevent abuse:
Endpoint | Limit | Window | Error Response |
---|---|---|---|
Magic Link Requests | 5 requests | 1 hour | {"error": "Too many magic link requests"} |
General API | 1000 requests | 1 hour | {"error": "Rate limit exceeded"} |
Transaction Creation | 100 requests | 1 minute | {"error": "Too many transactions per minute"} |
📊 Rate Limit Headers
Check these response headers to monitor your usage:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
🔥 Server Errors
Error | Status | Description | Action |
---|---|---|---|
INTERNAL_SERVER_ERROR |
500 | Unexpected server error | Retry request, contact support if persistent |
DATABASE_ERROR |
500 | Database connection or query error | Retry after a few seconds |
SERVICE_UNAVAILABLE |
500 | Service temporarily unavailable | Check status page, retry with exponential backoff |
🚨 Server Error Best Practices
- Implement exponential backoff for retries
- Don't retry immediately on 5xx errors
- Log errors for debugging
- Check our status page for known issues
🔧 Troubleshooting Guide
Common Debugging Steps
🔍 Step-by-Step Debugging
- Check HTTP Status Code - Determines error category
- Read Error Message - Specific issue description
- Verify Request Format - Headers, body, URL parameters
- Check Authentication - Token validity and format
- Validate Permissions - User access to resources
- Review Business Rules - Data constraints and validations
Error Handling Code Examples
// JavaScript error handling
async function handleApiResponse(response) {
if (!response.ok) {
const errorData = await response.json();
switch (response.status) {
case 400:
console.error('Validation error:', errorData.error);
if (errorData.field) {
highlightField(errorData.field);
}
break;
case 401:
console.error('Authentication error');
redirectToLogin();
break;
case 403:
console.error('Permission denied');
showPermissionError();
break;
case 422:
console.error('Business logic error:', errorData.error);
showBusinessError(errorData.error);
break;
case 429:
console.error('Rate limited');
const retryAfter = response.headers.get('Retry-After');
scheduleRetry(retryAfter);
break;
case 500:
console.error('Server error');
showRetryOption();
break;
default:
console.error('Unknown error:', response.status);
}
throw new Error(errorData.error);
}
return response.json();
}
Testing Error Scenarios
Use these cURL commands to test different error conditions:
# Test authentication error (no token)
curl -X GET "https://your-project.supabase.co/rest/v1/budgets"
# Test validation error (invalid email)
curl -X POST "https://your-project.supabase.co/functions/v1/auth-magic-link" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ANON_KEY" \
-d '{"email": "invalid-email"}'
# Test business logic error (insufficient balance)
curl -X POST "https://your-project.supabase.co/functions/v1/transactions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"budget_id": "your-budget-id",
"transaction_type": "expense",
"amount": 9999999,
"from_envelope_id": "envelope-id",
"payee_id": "payee-id"
}'
Getting Help
📞 Support Resources
- API Documentation: Complete API Reference
- Authentication Guide: Magic Link Auth Guide
- GitHub Issues: Report bugs
- Test Scripts: Validation scripts