XYZ.am Developer API Guide

Programmatic access to XYZ.am — shorten URLs, manage bookmarks and email aliases, and share encrypted secrets via a simple Bearer-token JSON API.

Quick Start

  1. Sign in to your dashboard and visit API Management to generate a token. Premium
  2. Copy the 64-character token. Treat it like a password — anyone with it can act on your account.
  3. Send it as a 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 }

Authentication

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
  • Token lifetime: 30 days from generation. Re-generate at any time from the dashboard — old tokens are invalidated immediately.
  • Rate limit: 1,000 calls per calendar month per user. Counter resets on the 1st of each month.
  • CORS: All endpoints set 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.
  • Plan gating: A few endpoints (shorten-api, alias-api) cap free accounts to 1 record. Premium accounts have no per-resource cap (only the monthly request limit applies).

Response Shape

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}.)

URL Shortener

POST /api/shorten-api.php

Create a short URL backed by xyz.am. Free accounts can create one short URL; premium is unlimited.

Request
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"
  }'
Body fields
FieldTypeRequiredNotes
actionstringyesAlways "create".
urlstringyesMust be a valid absolute URL.
customCodestringnoLetters, digits, -, _. Returns an error if already taken.
Success response
{
  "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".

Bookmarks

POST /api/bookmarks-api.php

Full CRUD for bookmarks organized into lists. The action field selects the operation.

action: add
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
}
action: get
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
{
  "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
{ "action": "delete", "bookmarkId": 9871 }

Bookmark Count

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 }

Email Aliases

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"
  }'
FieldTypeRequiredNotes
aliasNamestringyesLetters, digits, ., _, -. Becomes aliasName@xyz.am.
destinationEmailstringyesWhere mail is forwarded.
{
  "success": true,
  "message": "Email alias created successfully!",
  "alias": "newsletter-signups@xyz.am",
  "destination": "you@example.com",
  "plan": "premium"
}

Encrypted Secret Sharing

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.

kind: share — create a secret
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
  }'
FieldTypeRequiredNotes
secretstringyesUp to 10 KB.
passphrasestringnoRecipient must enter this to decrypt.
ttlint (seconds)noOne 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"
}
kind: generate — random password
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.

Login (Issue a Token)

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
}
Always call this endpoint over HTTPS and never store the user's password locally — keep only the returned token.

Common Errors

MessageCauseFix
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.

Reseller & WHMCS Integration

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.