API Documentation
Manage your short links and retrieve click statistics programmatically. The API speaks JSON and lives
under
http://adr.pm/api/v1.
Send Accept: application/json
with every request.
Authentication
All endpoints require a personal access token. Create one under your profile — the token is shown once, right after creation. Send it as a bearer token:
Authorization: Bearer <your-token>
Requests without a valid token receive 401 Unauthorized.
A token has the same access as the user who created it: addresses in your own groups.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/addresses | Paginated list of your addresses, newest first, with click counts. |
| POST | /api/v1/addresses | Create a short link. Body: group_id,
destination. Returns
201 Created. |
| GET | /api/v1/addresses/{id} | Show a single address with its click count. |
| PUT | /api/v1/addresses/{id} | Update the destination.
The short code never changes. |
| DELETE | /api/v1/addresses/{id} | Delete an address. Returns
204 No Content. |
| GET | /api/v1/stats | Click statistics across your groups. Optional
?group_id= filter. |
Accessing an address outside your groups returns
403; creating in a group you
are not a member of returns 404.
Example: create a short link
curl -X POST http://adr.pm/api/v1/addresses \
-H "Authorization: Bearer <your-token>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"group_id": 1, "destination": "https://example.com/very/long/url"}'
Response 201 Created:
{
"data": {
"id": 1,
"group_id": 1,
"destination": "https://example.com/very/long/url",
"identifyer": "xyz12",
"short_url": "http://adr.pm/xyz12",
"created_at": "2026-07-10T16:25:13.000000Z",
"updated_at": "2026-07-10T16:25:13.000000Z"
}
}
Example: statistics
curl http://adr.pm/api/v1/stats \
-H "Authorization: Bearer <your-token>" \
-H "Accept: application/json"
Response 200 OK:
{
"data": {
"active_links": 12,
"total_clicks": 340,
"clicks_this_week": 25,
"avg_clicks_per_link": 28,
"click_trends": {
"labels": ["Jun 11", "Jun 12", "Jun 13"],
"counts": [3, 7, 0]
},
"top_links": [
{
"id": 1,
"group_id": 1,
"destination": "https://example.com/very/long/url",
"identifyer": "xyz12",
"short_url": "http://adr.pm/xyz12",
"clicks_count": 120,
"created_at": "2026-07-10T16:25:13.000000Z",
"updated_at": "2026-07-10T16:25:13.000000Z"
}
]
}
}
click_trends covers the last 30
days, one entry per day.
Errors and pagination
Invalid input returns 422 Unprocessable Content
with a message and per-field errors:
{
"message": "The destination field must be a valid URL.",
"errors": {
"destination": ["The destination field must be a valid URL."]
}
}
The address list is paginated. Use ?page=
to navigate; each response includes links
and meta objects with the
current page, last page and totals.
Ready to try it out?
Create Account