API Token Management
Manage your API access token and monitor usage statistics
Your API Token
This is your full API token. Copy it now: for your security it will not be shown again.
Hidden for your security. The full token is shown only once, right after it is created. Lost it? Click Regenerate to create a new one.
Keep your token secure. Never share it publicly or commit it to version control. Regenerating creates a new token and immediately revokes the previous one.
Usage & Limits
Current hourQuick Start Guide
Full API documentationBase URL
Authentication
Send your API token in the Authorization header of every request:
Example
curl -X POST https://api.gjw.cx/api/v1/shorten \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/a/very/long/page"}'
Limits by plan
| Limit | Basic | Standard | Premium | Unlimited |
|---|---|---|---|---|
| Links | ||||
| New links per day | 10 | 200 | Unlimited | Unlimited |
| Links per account | 200 | 2,000 | 20,000 | Unlimited |
| Custom links | 3 | 8 | 190 | Unlimited |
| API requests | ||||
| Requests per hour | 1,000 | 1,000 | 1,000 | Unlimited |
| Requests per second | 10 | 10 | 10 | 50 |
| Concurrent requests | 5 | 5 | 5 | 10 |
Scroll the table sideways to see all plans.
How limits are counted
| Limit | What counts | Resets | When exceeded |
|---|---|---|---|
| New links per day | New links you shorten on the website, with the browser extensions, with bulk shortening or through the API. Deleting a link does not give it back. Shortening a URL that you already have as a regular link (sent without a custom code) returns that link and does not count. | 00:00 UTC+7 | 403 daily_limit_reached |
| Links per account | The links you have now, however they were made. Links in Trash do not count. | When you delete a link | 403 link_limit_reached |
| Custom links | The custom links you have now, not counting Trash. Each one also counts as a link. | When you delete one | 403 custom_limit_reached |
| Requests per hour | Every API request with a valid token, errors included, also concurrency_limited and server_busy. Requests rejected with rate_limited or temporarily_throttled do not count. | At the start of each clock hour | 429 rate_limited, Retry-After until the hour ends |
| Requests per second | The same requests, per clock second. | Every second | 429 rate_limited, Retry-After: 1 |
| Concurrent requests | Your requests that are in progress at the same time. | When a request finishes | 429 concurrency_limited, Retry-After: 1 |
- Unlimited means no quota. Requests per second, concurrent requests and system protection still apply to every plan, including at most 30 requests per second from one IP address, so one server cannot go above 30 per second.
- On plans with an hourly quota, responses carry
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Reset(the Unix time when the hour ends); they are not sent on Unlimited or on requests rejected before the quota check, such as a401. - System protection can also answer
429 server_busy,temporarily_throttled(after more than 50 requests rejected withrate_limitedorconcurrency_limitedin a minute) orip_blocked(after more than 20 invalid tokens in a minute): wait the number of seconds inRetry-After, then try again.
Endpoints
{"url": "...", "custom": "SpringLaunch", "description": "..."}; custom (6-100 letters, digits, - or _; letter case is ignored; see the rules) and description are optional. Returns 201, or 200 with the existing link for a URL you already shortened.limit (1-100, default 50) and cursor (use next_cursor from the previous page).{id} is the short code, e.g. abc123.Errors
Errors are JSON: {"error": "message", "code": "error_code"}. Codes:
invalid_json / invalid_url / invalid_slug / slug_too_short /
reserved_slug / invalid_description / invalid_limit / invalid_cursor (400),
missing_token / invalid_token (401),
account_blocked / domain_blocked / daily_limit_reached /
link_limit_reached / custom_limit_reached (403),
not_found (404), slug_taken (409), payload_too_large (413),
rate_limited / concurrency_limited / server_busy /
ip_blocked / temporarily_throttled (429, with Retry-After),
internal_error (500), timeout / unavailable /
slug_unavailable (503).