http://localhost:8080
The API uses JWT tokens for authentication. Include the token in the Authorization header:
Authorization: Bearer <your_token>
Create a new user account.
POST /api/auth/register
Request Body:
{
"email": string, // Required: Valid email address
"password": string // Required: Password
}
Example:
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "your_password"
}'
Response (200 OK):
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"email": "[email protected]"
}
}
Authenticate and receive a JWT token.
POST /api/auth/login
Request Body:
{
"email": string, // Required: Registered email address
"password": string // Required: Password
}
Example:
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "your_password"
}'
Response (200 OK):
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"email": "[email protected]"
}
}
Check if the service and database are running.
GET /health
Example:
curl http://localhost:8080/health
Response (200 OK):
"Healthy"
Response (503 Service Unavailable):
"Database unavailable"
Create a new shortened URL with optional custom code. Requires authentication.
POST /api/shorten
Request Body:
{
"url": string, // Required: The URL to shorten
"custom_code": string, // Optional: Custom short code
"source": string // Optional: Source of the request
}
Examples:
- Create with auto-generated code:
curl -X POST http://localhost:8080/api/shorten \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"url": "https://example.com",
"source": "curl-test"
}'
Response (201 Created):
{
"id": 1,
"user_id": 1,
"original_url": "https://example.com",
"short_code": "Xa7Bc9",
"created_at": "2024-03-01T12:34:56Z",
"clicks": 0
}
- Create with custom code:
curl -X POST http://localhost:8080/api/shorten \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"url": "https://example.com",
"custom_code": "example",
"source": "curl-test"
}'
Response (201 Created):
{
"id": 2,
"user_id": 1,
"original_url": "https://example.com",
"short_code": "example",
"created_at": "2024-03-01T12:34:56Z",
"clicks": 0
}
Error Responses:
Invalid URL (400 Bad Request):
{
"error": "URL must start with http:// or https://"
}
Custom code taken (400 Bad Request):
{
"error": "Custom code already taken"
}
Invalid custom code (400 Bad Request):
{
"error": "Custom code must be 1-32 characters long and contain only letters, numbers, underscores, and hyphens"
}
Unauthorized (401 Unauthorized):
{
"error": "Unauthorized"
}
Retrieve all shortened URLs for the authenticated user.
GET /api/links
Example:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/links
Response (200 OK):
[
{
"id": 1,
"user_id": 1,
"original_url": "https://example.com",
"short_code": "Xa7Bc9",
"created_at": "2024-03-01T12:34:56Z",
"clicks": 5
},
{
"id": 2,
"user_id": 1,
"original_url": "https://example.org",
"short_code": "example",
"created_at": "2024-03-01T12:35:00Z",
"clicks": 3
}
]
Use the shortened URL to redirect to the original URL. Source tracking via query parameter is supported.
GET /{short_code}?source={source}
Example:
curl -i http://localhost:8080/example?source=email
Response (307 Temporary Redirect):
HTTP/1.1 307 Temporary Redirect
Location: https://example.com
Error Response (404 Not Found):
{
"error": "Not found"
}
- Length: 1-32 characters
- Allowed characters: letters, numbers, underscores, and hyphens
- Case-sensitive
- Cannot use reserved words: ["api", "health", "admin", "static", "assets"]
Currently, no rate limiting is implemented.
- All timestamps are in UTC
- Click counts are incremented on successful redirects
- Source tracking is supported both at link creation and during redirection via query parameter
- Custom codes are case-sensitive
- URLs must include protocol (http:// or https://)
- All create/read operations require authentication
- Users can only see and manage their own links
- 200: Success
- 201: Created
- 307: Temporary Redirect
- 400: Bad Request (invalid input)
- 401: Unauthorized (missing or invalid token)
- 404: Not Found
- 503: Service Unavailable
-- Users table for authentication
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL
);
-- Links table with user association
CREATE TABLE links (
id SERIAL PRIMARY KEY,
original_url TEXT NOT NULL,
short_code VARCHAR(8) NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
clicks BIGINT NOT NULL DEFAULT 0,
user_id INTEGER REFERENCES users(id)
);
-- Click tracking with source information
CREATE TABLE clicks (
id SERIAL PRIMARY KEY,
link_id INTEGER REFERENCES links(id),
source TEXT,
query_source TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_short_code ON links(short_code);
CREATE INDEX idx_user_id ON links(user_id);
CREATE INDEX idx_link_id ON clicks(link_id);