Download OpenAPI specification:
Fearly.eu is a free, privacy-first URL shortener and QR code generator, hosted entirely in the EU. This API lets an account holder shorten URLs, list their own links and campaigns, and manage their own API keys — everything the browser extension and the account dashboard already do, available for your own scripts and apps too.
No visitor tracking, no third-party analytics, no data sales. Rate limits apply per account (not per key) and match whatever tier your account is on — creating extra keys does not grant extra quota.
Get a key by registering (POST /auth/register), logging into an
existing account (POST /auth/login), or from the "Manage API Key"
page in your dashboard if you already have an account.
Creates a brand-new registered_anonymous account (no email or
password) and issues its first API key in one call. No
authentication required. Rate-limited per IP address.
| label | string A name for this key, e.g. "My Script". Defaults to "API Client". |
{- "label": "My Script"
}{- "account_number": "string",
- "account_type": "registered_anonymous",
- "tier_name": "string",
- "api_key": {
- "id": 0,
- "key_prefix": "fearly_ab12",
- "key": "fearly_ab12cd34ef56gh78ij90",
- "label": "string",
- "scopes": [
- "string"
], - "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z"
}
}Authenticates with either an account number or an email+password pair, and issues a new API key on that account. Existing keys on the account keep working — this does not replace them.
| account_number | string Use this OR email+password, not both. |
string <email> | |
| password | string |
| label | string A name for the new key. Defaults to "API Client". |
{- "email": "you@example.com",
- "password": "your-password",
- "label": "My Script"
}{- "account_number": "string",
- "account_type": "registered_anonymous",
- "tier_name": "string",
- "api_key": {
- "id": 0,
- "key_prefix": "fearly_ab12",
- "key": "fearly_ab12cd34ef56gh78ij90",
- "label": "string",
- "scopes": [
- "string"
], - "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z"
}
}Returns every key on your account, active and revoked. The plaintext key itself is never included — only the prefix.
curl https://www.fearly.eu/api/v1/keys \ -H "Authorization: Bearer fearly_xxxxxxxxxxxx"
{- "keys": [
- {
- "id": 0,
- "key_prefix": "fearly_ab12",
- "key": "fearly_ab12cd34ef56gh78ij90",
- "label": "string",
- "scopes": [
- "string"
], - "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z"
}
]
}Creates another key on the same account. Capped at 10 active keys per account — revoke an unused one if you hit the limit.
| label | string |
{- "label": "Staging server"
}{- "api_key": {
- "id": 0,
- "key_prefix": "fearly_ab12",
- "key": "fearly_ab12cd34ef56gh78ij90",
- "label": "string",
- "scopes": [
- "string"
], - "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z"
}
}Immediately invalidates a key. Anything using it stops working right away. This cannot be undone.
| id required | integer |
curl -X DELETE https://www.fearly.eu/api/v1/keys/42 \ -H "Authorization: Bearer fearly_xxxxxxxxxxxx"
{- "message": "string"
}Works with or without a key — anonymous requests get the (lower) anonymous rate limit; an authenticated request gets your account's tier limit, tracks the link on your account, and unlocks custom slugs and password protection.
| long_url required | string <uri> |
| custom_code | string [ 3 .. 40 ] characters A custom slug instead of a random one. 3–40 characters,
letters/numbers/dashes/underscores only. Requires an
account whose tier allows custom slugs
( |
| password | string If set, visitors must enter this password before the link redirects. Requires authentication. |
| analytics_enabled | boolean or null Omit to use your account default. |
{- "custom_code": "string",
- "password": "string",
- "analytics_enabled": true
}{- "short_code": "abc123",
}| limit | integer <= 100 Default: 50 |
| offset | integer Default: 0 |
curl "https://www.fearly.eu/api/v1/urls?limit=20&offset=0" \ -H "Authorization: Bearer fearly_xxxxxxxxxxxx"
{- "urls": [
- {
- "short_code": "string",
- "long_url": "string",
- "short_url": "string",
- "created_at": "string",
- "expires_at": "string",
- "click_count": 0,
- "is_custom_alias": true,
- "has_qr_code": true,
- "qr_code_url": "string",
- "analytics_enabled": true
}
], - "total_count": 0,
- "limit": 0,
- "offset": 0
}curl https://www.fearly.eu/api/v1/campaigns \ -H "Authorization: Bearer fearly_xxxxxxxxxxxx"
{- "campaigns": [
- {
- "id": 0,
- "name": "string",
- "description": "string",
- "utm_campaign": "string",
- "start_date": "string",
- "end_date": "string",
- "is_active": true,
- "is_default": true
}
]
}Use default as the id to get URLs that aren't assigned to any specific campaign.
| id required | string Example: default |
curl https://www.fearly.eu/api/v1/campaigns/default \ -H "Authorization: Bearer fearly_xxxxxxxxxxxx"
{- "urls": [
- {
- "short_code": "string",
- "long_url": "string",
- "short_url": "string",
- "created_at": "string",
- "expires_at": "string",
- "click_count": 0,
- "is_custom_alias": true,
- "has_qr_code": true,
- "analytics_enabled": true,
- "status": "string",
- "is_blocked": true,
- "utm_source": "string",
- "utm_medium": "string",
- "utm_term": "string",
- "utm_content": "string",
- "utm_id": "string"
}
]
}