Programmatic access to XYZ.am — shorten URLs, manage bookmarks and email aliases, and share encrypted secrets via a simple Bearer-token JSON API.
Bearer header on every request.Verify your key works by counting your bookmarks:
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://xyz.am/api/count-bookmarks.php
Expected reply:
{ "success": true, "count": 42 }
All endpoints accept a Bearer token in two equivalent ways:
Authorization: Bearer YOUR_API_TOKEN
# or, as a query parameter (handy for browser testing — but never log these):
?token=YOUR_API_TOKEN
Access-Control-Allow-Origin: * so they're callable from browser extensions or front-end apps. We recommend a server-side proxy to keep your token off the client.shorten-api, alias-api) cap free accounts to 1 record. Premium accounts have no per-resource cap (only the monthly request limit applies).Every endpoint returns JSON. Successful responses always include success: true. Failures look like:
{ "success": false, "message": "Invalid or expired token" }
HTTP status is almost always 200 — check the success field, not the status code. (The one exception is /api/spx-login-link.php, which uses {ok, error}.)
POST /api/shorten-api.php
Create a short URL backed by xyz.am. Free accounts can create one short URL; premium is unlimited.
curl -X POST https://xyz.am/api/shorten-api.php \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "create",
"url": "https://example.com/very/long/path?utm_source=newsletter",
"customCode": "spring-promo"
}'
| Field | Type | Required | Notes |
|---|---|---|---|
action | string | yes | Always "create". |
url | string | yes | Must be a valid absolute URL. |
customCode | string | no | Letters, digits, -, _. Returns an error if already taken. |
{
"success": true,
"shortCode": "spring-promo",
"shortUrl": "https://xyz.am/spring-promo",
"plan": "premium"
}
If the same url was already shortened by your account, the existing short URL is returned with "message": "URL already shortened".
POST /api/bookmarks-api.php
Full CRUD for bookmarks organized into lists. The action field selects the operation.
curl -X POST https://xyz.am/api/bookmarks-api.php \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "add",
"url": "https://example.com",
"title": "Example",
"category": "Reference",
"notes": "Found via XYZ",
"list_id": 12
}'
Only url is required. list_id defaults to your default list.
{
"success": true,
"message": "Bookmark added",
"bookmark_id": 9871,
"list_id": 12
}
curl -X POST https://xyz.am/api/bookmarks-api.php \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "action": "get", "list_id": 12 }'
Both list_id and category are optional filters.
{
"success": true,
"list_id": 12,
"bookmarks": [ { "id": 9871, "url": "...", "title": "...", ... } ],
"categories": [ "Reference", "Work", "Reading" ],
"lists": [ { "id": 12, "name": "Saved" }, ... ]
}
{
"action": "update",
"bookmarkId": 9871,
"title": "Updated title",
"category": "Work",
"list_id": 15
}
Pass list_id to move a bookmark between lists. Only bookmarkId is required.
{ "action": "delete", "bookmarkId": 9871 }
GET /api/count-bookmarks.php
Cheap endpoint that returns the total bookmark count for the authenticated user.
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://xyz.am/api/count-bookmarks.php
{ "success": true, "count": 42 }
POST /api/alias-api.php
Create an @xyz.am alias that forwards to your real inbox. Free accounts can create one alias; premium is unlimited.
curl -X POST https://xyz.am/api/alias-api.php \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"aliasName": "newsletter-signups",
"destinationEmail": "you@example.com"
}'
| Field | Type | Required | Notes |
|---|---|---|---|
aliasName | string | yes | Letters, digits, ., _, -. Becomes aliasName@xyz.am. |
destinationEmail | string | yes | Where mail is forwarded. |
{
"success": true,
"message": "Email alias created successfully!",
"alias": "newsletter-signups@xyz.am",
"destination": "you@example.com",
"plan": "premium"
}
POST /api/submit-secret.php
Encrypt and share a one-time-view secret, or generate a strong random password. Two operations selected by the kind field.
curl -X POST https://xyz.am/api/submit-secret.php \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"kind": "share",
"secret": "the message to encrypt",
"passphrase": "optional second factor",
"ttl": 3600
}'
| Field | Type | Required | Notes |
|---|---|---|---|
secret | string | yes | Up to 10 KB. |
passphrase | string | no | Recipient must enter this to decrypt. |
ttl | int (seconds) | no | One of 300, 1800, 3600, 14400, 43200, 86400, 259200, 604800. Default 3600 (1 hour). |
{
"success": true,
"secret_id": "f2c1...",
"url": "https://xyz.am/s/f2c1...",
"expires_in": 3600,
"expires_at": "2026-04-19T18:00:00Z"
}
curl -X POST https://xyz.am/api/submit-secret.php \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "kind": "generate", "length": 24 }'
{ "success": true, "password": "G7&kX9pZ...", "length": 24 }
length is optional, between 8 and 64. Default 16.
POST /api/login-api.php
Exchange email + password for a 30-day Bearer token. Public — no token required. Useful for native apps and browser extensions that want to drive the dashboard sign-in flow.
curl -X POST https://xyz.am/api/login-api.php \
-H "Content-Type: application/json" \
-d '{ "email": "you@example.com", "password": "•••••••••" }'
{
"success": true,
"token": "abcdef0123…",
"userId": 123,
"userName": "Jane Doe",
"plan": "premium",
"membershipExpiry": "2026-12-31",
"isPremium": true
}
| Message | Cause | Fix |
|---|---|---|
Authorization token required |
No Authorization header or ?token=. |
Include the Bearer header. |
Invalid or expired token |
Token doesn't match the user_tokens table or is older than 30 days. |
Generate a new token, or call /api/login-api.php to get a fresh one. |
Free users can only create one … |
You hit the free-tier limit on shorten-api or alias-api. |
Upgrade to premium, or delete your existing record. |
Custom code already exists |
The customCode on shorten-api is already in use. |
Pick a different code, or omit it to get an auto-generated one. |
Invalid URL format |
The URL didn't pass FILTER_VALIDATE_URL. |
Include the scheme (https://) and a valid host. |
A separate set of admin endpoints exists for resellers and billing platforms (WHMCS, etc.) — provisioning users, adjusting credits, generating SSO login links, suspending/terminating accounts. These use a static system key, not a per-user Bearer token, and are restricted to vetted partners.
If you're integrating xyz.am with your billing system or running a reseller program, please contact us for credentials and the partner-API reference.