Error Handling
Authentication Errors
// Missing API Key
{
"error": "Authorization header missing",
"status": 401
}
// Invalid API Key Format
{
"error": "Invalid API key format",
"status": 401
}
// Invalid/Inactive API Key
{
"error": "Invalid API key",
"status": 401
}
// API Key Not Found
{
"error": "API key not found or inactive",
"status": 401
}
Subscription & Permission Errors
// Starter Subscription API Restriction
{
"error": "API access is not available for Starter subscription. Please upgrade your plan to use API features.",
"status": 403
}
// Smartlink Limit Reached
{
"error": "Subscription limit reached. You can create up to 3 smartlinks with your current plan.",
"status": 403
}
// User Doesn't Own Smartlink
{
"error": "You do not have permission to update this smartlink",
"status": 403
}
// Feature Not Available in Plan
{
"error": "macOsAppLink and windowsAppLink are only available for Professional and Enterprise plans",
"status": 403
}
// Banned User Account
{
"error": "User account is banned",
"status": 403
}
Validation Errors
// Missing Required Fields
{
"error": "Smartlink type is required",
"status": 400
}
// Invalid JSON Format
{
"error": "Invalid JSON format",
"status": 400
}
// Schema Validation Failure
{
"error": "Configuration validation failed",
"details": [
{
"code": "too_big",
"maximum": 64,
"type": "string",
"inclusive": true,
"exact": false,
"message": "Smartlink name must contain at most 64 character(s)",
"path": ["smartlinkName"]
}
],
"status": 400
}
// Invalid URL Format
{
"error": "Invalid URL format provided",
"status": 400
}
// Invalid Smartlink Type
{
"error": "Invalid smartlink type. Must be one of: App, Url, Landing, QRTag, DigiCard, TxtBin",
"status": 400
}
// Invalid Custom URL
{
"error": "Custom URL must be 6 characters, alphanumeric only",
"status": 400
}
Resource Errors
// Smartlink Not Found
{
"error": "Smartlink not found",
"status": 404
}
// Smartlink Doesn't Belong to User
{
"error": "Smartlink not found or doesn't belong to user",
"status": 404
}
// Already Deleted Smartlink
{
"error": "Cannot update deleted smartlink",
"status": 404
}
Conflict Errors
// URL Already Exists
{
"error": "Smartlink URL already exists",
"status": 409
}
// Duplicate Custom URL
{
"error": "A smartlink with this custom URL already exists",
"status": 409
}
URL Safety Errors
// Unsafe URL Detected
{
"error": "Unsafe URLs found: https://malicious-site.com",
"status": 400
}
// Multiple Unsafe URLs
{
"error": "Multiple unsafe URLs detected in configuration",
"status": 400
}
Rate Limiting
API requests are rate-limited to prevent abuse. When you exceed the limit:
{
"error": "Too many requests, please try again later.",
"status": 429,
"retryAfter": 60
}
Rate Limits by Plan:
- Starter: Not applicable (API not available)
- Professional: 1000 requests per hour
- Enterprise: 5000 requests per hour
Server Errors
// Internal Server Error
{
"error": "Internal server error",
"status": 500
}
// Service Temporarily Unavailable
{
"error": "Service temporarily unavailable. Please try again later.",
"status": 503
}
// Database Connection Error
{
"error": "Database connection failed. Please try again.",
"status": 503
}
Error Response Format
All error responses follow a consistent format:
{
"error": "Human-readable error message",
"status": 400,
"details": [/* Optional: validation details */],
"code": "OPTIONAL_ERROR_CODE",
"timestamp": "2024-01-15T10:30:00.000Z"
}
Testing Error Scenarios
Use these examples to test error handling in your application:
Invalid API Key
curl -X GET https://relink.is/api/v1/smartlink \
-H "Authorization: Bearer rlk_invalid_key"
Missing Authorization
curl -X GET https://relink.is/api/v1/smartlink
Invalid JSON
curl -X POST https://relink.is/api/v1/smartlink \
-H "Authorization: Bearer rlk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ invalid json }'
Duplicate URL Creation
curl -X POST https://relink.is/api/v1/smartlink \
-H "Authorization: Bearer rlk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"config": {
"smartlinkTempUrl": "existing-url",
"smartlinkName": "Duplicate Test",
"smartlinkType": "App"
}
}'
Non-existent Smartlink
curl -X GET "https://relink.is/api/v1/smartlink?id=non_existent_id" \
-H "Authorization: Bearer rlk_your_api_key_here"
Best Practices for Error Handling
- Always check status codes before processing response data
- Implement retry logic for 5xx server errors with exponential backoff
- Handle rate limiting by respecting the
retryAfter
header - Validate data client-side before sending to reduce 400 errors
- Store and log error responses for debugging and monitoring
- Provide user-friendly messages based on error types
- Implement proper error boundaries in your application
Example Error Handling Code
async function createSmartlink(smartlinkData) {
try {
const response = await fetch('/api/v1/smartlink', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(smartlinkData)
});
if (!response.ok) {
const error = await response.json();
switch (error.status) {
case 400:
throw new Error(`Validation error: ${error.error}`);
case 401:
throw new Error('Invalid API key. Please check your credentials.');
case 403:
throw new Error('Permission denied or subscription limit reached.');
case 409:
throw new Error('Smartlink URL already exists. Please choose a different URL.');
case 429:
throw new Error('Rate limit exceeded. Please try again later.');
case 500:
throw new Error('Server error. Please try again.');
default:
throw new Error(`Unexpected error: ${error.error}`);
}
}
return await response.json();
} catch (error) {
console.error('Smartlink creation failed:', error);
throw error;
}
}