API Documentation
Shorten links, fetch analytics, and manage URLs programmatically. All endpoints return JSON and require a Bearer token.
https://urlly.me/api/v1
Authentication
Send your token in the Authorization header on every request
| Header | Value |
|---|---|
| Authorization | Bearer <token> |
| Accept | application/json |
| Content-Type | application/json (POST only) |
Generate tokens from your API Settings. Tokens are shown only once — store them securely. Missing or invalid tokens return 401 Unauthorized.
# Save your token in an environment variable export URLLY_TOKEN="your_token_here" # Include it in every request curl https://urlly.me/api/v1/shorten \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json"
/api/v1/shorten
201 Created
Shorten a URL. Optionally provide a custom alias (3–20 chars) and a verified custom domain.
Request Body
| Field | Type | Required | Notes |
|---|---|---|---|
| long_url | string | Yes | Valid URL, max 2048 chars |
| custom_alias | string | No | [a-z0-9_-], 3–20 chars |
| domain_id | integer | No | ID of a verified custom domain you own. Omit to use the default domain. |
Response
{
"success": true,
"short_url": "https://urlly.me/my-link",
"original_url": "https://example.com/...",
"hash": "my-link",
"created_at": "2026-03-19T10:00:00+00:00"
}
Example Request
# Auto-generated short code curl -X POST \ "https://urlly.me/api/v1/shorten" \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"long_url":"https://example.com/long-page"}' # With custom alias curl -X POST \ "https://urlly.me/api/v1/shorten" \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "long_url": "https://example.com/long-page", "custom_alias": "my-link" }'
/api/v1/stats/{hash}
200 OK
Click analytics for a link you own — total clicks, daily breakdown, device split, top browsers.
URL Parameter
| Parameter | Description |
|---|---|
| hash | The short code or custom alias of your link |
Response
{
"success": true,
"hash": "aBcDeFg",
"short_url": "https://urlly.me/aBcDeFg",
"original_url": "https://example.com",
"is_active": true,
"stats": {
"total_clicks": 142,
"clicks_by_day": [
{ "date": "2026-03-19", "total": 108 }
],
"devices": { "desktop": 80, "mobile": 62 },
"browsers": { "Chrome": 95, "Safari": 47 }
}
}
Example Request
curl -X GET \ "https://urlly.me/api/v1/stats/aBcDeFg" \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Accept: application/json"
/api/v1/links
200 OK · Paginated
Paginated list of all links you've created, newest first. 20 items per page.
Query Parameters
| Parameter | Default | Description |
|---|---|---|
| page | 1 | Page number |
Response
{
"success": true,
"data": [
{
"hash": "aBcDeFg",
"short_url": "https://urlly.me/aBcDeFg",
"original_url": "https://example.com",
"clicks": 142,
"is_active": true,
"created_at": "2026-03-19T10:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 20,
"total": 58
}
}
Example Request
# First page curl -X GET \ "https://urlly.me/api/v1/links" \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Accept: application/json" # Page 2 curl -X GET \ "https://urlly.me/api/v1/links?page=2" \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Accept: application/json"
Custom Domains
Serve short links from your own domain instead of the default one
Authenticated users can add verified custom domains. Once verified, pass its domain_id to the POST /shorten endpoint to create short links under that domain.
How to set up
- 1.Go to Custom Domains in your dashboard and add your domain.
- 2.Add a DNS CNAME record pointing your subdomain to
urlly.me. - 3.Add the TXT verification record shown in the dashboard, then click Verify.
- 4.Once verified, note the domain's
idand pass it asdomain_idin API calls.
Example: shorten with a custom domain
# Shorten using your custom domain (id: 3) curl -X POST \ "https://urlly.me/api/v1/shorten" \ -H "Authorization: Bearer $URLLY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "long_url": "https://example.com/long-page", "domain_id": 3 }' # Response — short_url uses your domain { "success": true, "short_url": "https://links.yourdomain.com/aBcDeFg", "original_url": "https://example.com/long-page", "hash": "aBcDeFg", "created_at": "2026-03-21T10:00:00+00:00" }
Rate Limiting
2000 requests per 1 min per token
| Response Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests per window (2000) |
| X-RateLimit-Remaining | Requests remaining this window |
| Retry-After | Seconds until window resets (429 only) |
Retry-After to know when to retry.
429 Response
HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 2000 X-RateLimit-Remaining: 0 Retry-After: 47 { "message": "Too Many Attempts." }
Error Codes
All errors return JSON with a message field. Validation errors (422) also include an errors object.
| Status | Meaning | Common Cause |
|---|---|---|
| 401 | Unauthorized | Missing or invalid token |
| 403 | Forbidden | Resource doesn't belong to you |
| 404 | Not Found | Link hash doesn't exist |
| 422 | Validation Error | Invalid fields or duplicate alias |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Something went wrong on our end |
Error Response Examples
# 401 Unauthorized { "message": "Unauthenticated." } # 404 Not Found { "error": "not_found", "message": "Link not found or does not belong to you." } # 422 Validation Error { "message": "The long_url field is required.", "errors": { "long_url": [ "The long_url field is required." ] } } # 422 Unsafe URL { "error": "unsafe_url", "message": "This URL has been flagged as unsafe." }
Ready to build?
Generate a token and make your first API call in seconds.