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

Source: https://blinkhop.com/docs/quickstart

## 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

```bash
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:

```js
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
```

```python
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:

```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:

```bash
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.

## 4. Get only the link

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

```bash
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:

```json
{
  "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](https://blinkhop.com/pricing#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:

```js
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](https://blinkhop.com/docs/api) for every endpoint: bulk creation, link lookup, the link expander and reports.
- Copy ready-made [code samples](https://blinkhop.com/docs/code-samples) for Node.js, Python, Go, PHP, PowerShell, Google Sheets and more.
- Let your AI assistant do it: connect the [MCP server](https://blinkhop.com/mcp) to Claude, ChatGPT, Cursor or VS Code.
- Import the [OpenAPI spec](https://blinkhop.com/openapi.json) into Postman, Insomnia or your code generator.
