Developer docs

Quickstart: your first short link from code

One POST request, no API key, no sign-up. Go from zero to a working short link, then learn the few details worth knowing before you ship.

View as Markdown

API at a glance

Base URL
https://api.blinkhop.com/v1
MCP server
https://mcp.blinkhop.com/mcp
API key
Not needed to start
Limits
20 links/min, 300/day per IP

POST /v1/links

Live, no key needed

This creates a real short link on zou.sh, like the form on our home page. It counts toward your limit of 20 links per minute.

1. Send one request

The Blinkhop API lives at https://api.blinkhop.com/v1. To shorten a URL, send it to the /links endpoint:

POST/v1/links

curl https://api.blinkhop.com/v1/links \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/a/very/long/link"}'

That’s the whole setup. There is no key to create, no account and nothing to install. The same request works from any language that can send HTTP:

const res = await fetch("https://api.blinkhop.com/v1/links", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.com/a/very/long/link" }),
});
const link = await res.json();
console.log(link.short_url); // https://zou.sh/7Kp2x
import requests

r = requests.post(
    "https://api.blinkhop.com/v1/links",
    json={"url": "https://example.com/a/very/long/link"},
    timeout=10,
)
print(r.json()["short_url"])  # https://zou.sh/7Kp2x

2. Read the response

A successful call returns the link as JSON:

{
  "id": "lnk_7Kp2x",
  "code": "7Kp2x",
  "short_url": "https://zou.sh/7Kp2x",
  "url": "https://example.com/a/very/long/link",
  "qr_url": "https://zou.sh/7Kp2x/qr",
  "preview_url": "https://zou.sh/7Kp2x+",
  "clicks": 0,
  "created_at": "2026-10-11T14:02:11Z"
}
Field Description
short_url The link to share. It redirects to url with an HTTP 302.
code The part after zou.sh/. Lookups ignore letter case.
url The destination, normalized (a missing https:// is added).
qr_url A print-ready SVG QR code of the short link.
preview_url A public page that shows the destination and the click count before anyone visits.
clicks Human clicks so far. Bots and link previews are not counted.
created_at Creation time, ISO 8601 in UTC.

The status code tells you what happened. 201 Created means a new link. 200 OK means the same URL had already been shortened without a custom ending, so you get the existing link back. Retrying a request never creates duplicates.

3. Choose the ending

Add an alias to pick the ending yourself:

curl https://api.blinkhop.com/v1/links \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/spring", "alias": "spring-sale"}'

Endings use 3 to 40 letters, numbers, dashes or underscores, and start with a letter or a number. They are unique regardless of letter case: zou.sh/Spring-Sale and zou.sh/spring-sale are the same link. If the ending is taken or reserved, the API answers 409 with the code alias_taken, so you can suggest another one.

Add ?format=text and the API returns the short URL as plain text, which is handy in shell scripts:

curl -s "https://api.blinkhop.com/v1/links?format=text" \
  --data-urlencode "url=https://example.com/report?quarter=q3&year=2026"
# https://zou.sh/q8Hn4

The API also accepts form-encoded bodies, as above. Use --data-urlencode so that & and ? inside your URL survive the trip.

5. Handle errors and limits

Errors come back as JSON with a stable code, a readable message and, when it applies, the field at fault:

{
  "error": {
    "code": "invalid_url",
    "message": "That does not look like a valid URL.",
    "field": "url"
  }
}

Branch on code, not on message: messages may be reworded, codes won’t. The most common ones:

HTTP Code When
400 missing_url The request has no url.
422 invalid_url The URL is malformed, not http(s), or points to a private address.
422 unsafe_destination The domain is on our phishing and malware blocklist.
409 alias_taken The custom ending is taken or reserved.
429 rate_limited Too many links in a short time. Wait Retry-After seconds.

Without a key you can create 20 links per minute and 300 per day per IP address. Every response from POST /links carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers, and a 429 adds Retry-After. API keys with higher limits come with accounts, which are in early access.

6. Call it from a web page

The API sends Access-Control-Allow-Origin: *, so you can call it straight from the browser, with no proxy. Nothing secret is involved, since no key is needed:

document.querySelector("#share").addEventListener("click", async () => {
  const res = await fetch("https://api.blinkhop.com/v1/links", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ url: location.href }),
  });
  const { short_url } = await res.json();
  await navigator.clipboard.writeText(short_url);
});

Next steps

  • Read the API reference for every endpoint: bulk creation, link lookup, the link expander and reports.
  • Copy ready-made code samples for Node.js, Python, Go, PHP, PowerShell, Google Sheets and more.
  • Let your AI assistant do it: connect the MCP server to Claude, ChatGPT, Cursor or VS Code.
  • Import the OpenAPI spec into Postman, Insomnia or your code generator.