Feature

A Free URL Shortener API With No Authentication

POST a long URL, get a short one back. No API key, no account, no monthly quota — just an HTTP request from cURL, Python, JavaScript, Go, or anything else that speaks JSON.

  • No API key
  • No signup
  • JSON in, JSON out
  • No monthly cap

Quick start

Pick a language and run it. There is no authentication step — the request below is the entire integration.

curl -X POST https://zip1.io/api/create \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-long-url.com/some/very/deep/path"}'
import requests

response = requests.post(
    "https://zip1.io/api/create",
    json={"url": "https://your-long-url.com/some/very/deep/path"},
)
print(response.json()["short_url"])  # https://zip1.io/abc123
const response = await fetch("https://zip1.io/api/create", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://your-long-url.com/some/very/deep/path" })
});

const data = await response.json();
console.log(data.short_url); // https://zip1.io/abc123
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"url": "https://your-long-url.com/some/very/deep/path"}`)
	resp, err := http.Post("https://zip1.io/api/create", "application/json", bytes.NewBuffer(body))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, _ := io.ReadAll(resp.Body)
	fmt.Println(string(data))
}

A successful request returns HTTP 200 with the short URL and creation timestamp:

{
  "short_url": "https://zip1.io/abc123",
  "created_at": "2026-07-06T12:00:00.482913+00:00"
}

Every option in one request — a custom slug that dies after 100 clicks, expires at year end, and asks visitors for a password:

curl -X POST https://zip1.io/api/create \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-long-url.com/campaign",
    "alias": "spring-2026",
    "max-clicks": 100,
    "expiration-time": "2027-12-31T23:59:00Z",
    "password": "open.sesame1",
    "description": "Spring launch — email cohort A"
  }'

Keep the alias to 12 characters. Anything longer is silently truncated rather than rejected — spring-launch becomes spring-launc — so always read short_url back from the response.

Endpoints

Endpoint Rate limit (per IP) What it does
POST /api/create 10 / minute Create a short link
GET /api/stats/<code> 30 / minute Click stats as JSON
GET /api/check-alias?alias=<slug> 60 / minute Check if a custom slug is free
GET /export/<code>/<format> Export click data as csv, json, xlsx, or xml (csv arrives as a ZIP of several CSVs)

Parameters for POST /api/create

Field Required Rules
url Required A valid http(s) URL — the redirect destination
alias Optional Custom slug: letters, numbers, -, _. Truncated to the first 12 characters
password Optional 8+ characters with a letter, a number, and @ or .
max-clicks Optional Positive integer — the link stops redirecting after N clicks
expiration-time Optional ISO 8601 with timezone, at least 5 minutes ahead (e.g. 2026-12-31T23:59:00Z)
description Optional Label of up to 100 characters, shown on the stats page

Stats response

GET /api/stats/<code> returns totals, uniques, and top countries for any short link — no ownership check, no token:

{
  "message": "Statistics retrieved successfully",
  "data": {
    "short_code": "spring-2026",
    "total_clicks": 87,
    "unique_clicks": 64,
    "creation_date": "2026-07-06T12:00:00.482913+00:00",
    "last_click": "2026-07-06 15:42:11",
    "click_limit": "100",
    "expiration_time": "2026-12-31T23:59:00+00:00",
    "is_password_protected": true,
    "top_countries": [{"country": "United States", "clicks": 31}],
    "recent_clicks": []
  }
}

Two quirks worth coding around: click_limit is a string (or null), and last_click uses a space rather than a T and carries no UTC offset. creation_date is a full ISO 8601 timestamp for every link regardless of how it was made — before 2026-09-01 website-created links reported only a clock time. top_countries is capped at three entries, and recent_clicks is always empty — use the export endpoint for per-click data. Full details in the API documentation.

Need spreadsheets instead? The same analytics export as CSV, XLSX, JSON, or XML via /export/<code>/<format>.

Rate limits

Because there are no API keys, limits apply per IP address: 10 link creations per minute, 30 stats reads per minute, 60 alias checks per minute. There is no daily or monthly quota — create as many links over time as you need. The limits exist to stop abuse, not to sell an upgrade.

Exceed a limit and you get HTTP 429:

{"error": "ratelimit exceeded 10 per 1 minute"}

Back off until the minute window resets and retry. If you legitimately need more throughput, get in touch.

Error responses

Errors return a JSON body with a message field and a conventional status code — except 429, where the rate limiter responds with an error field:

Status When Example message
400 Missing or malformed url "Start the address with https:// — try https://example.com" (plus a reason code)
400 Invalid alias, password, max-clicks, expiration-time, or description "max-clicks must be a positive integer"
403 Destination is on the abuse blocklist "URL is blocked"
409 Requested alias is already taken "Alias already exists"
404 Stats requested for an unknown short code "Short link not found"
429 Rate limit exceeded {"error": "ratelimit exceeded 10 per 1 minute"}

How it compares to the bit.ly and TinyURL APIs

Most URL shortener APIs assume an account, an access token, and a plan. If you just need short links from a script, a CI job, or an AI agent, that setup is the slowest part. Here's the honest comparison:

Capability zip1.io API bit.ly API TinyURL API
Authentication None Account + OAuth token Account + API token
Monthly link quota None — rate limit only Capped on the free plan Capped on the free plan
Custom slugs via API, free Yes Limited on free plan Limited on free plan
Password-protected links Yes, free Not offered Not offered
Click caps (max-clicks) Yes No No
Click analytics via API, free Yes Limited free tier Paid plans
Signup required No Yes Yes

Plan details for bit.ly and TinyURL are as published on their pricing pages and may change. The structural difference is stable: both authenticate every request and meter link creation by plan; zip1.io does neither.

Built for AI agents too

The same API is exposed as a Model Context Protocol server, so agents like Claude can mint and track short links as native tools instead of raw HTTP calls:

claude mcp add --transport http zip1 https://zip1.io/mcp

No key to provision for the agent either — the no-auth design is what makes zero-config agent integration possible.

FAQ

  • Do I need an API key?

    No. Zero authentication — no API key, no OAuth token, no account. Send a POST request to /api/create and you get a short URL back. Rate limiting is per IP address instead of per key.

  • Is the API free, and what are the rate limits?

    Free, with no paid tier and no monthly link quota. Limits are per IP: 10 link creations per minute, 30 stats requests per minute, 60 alias checks per minute. Exceeding one returns HTTP 429 until the window resets.

  • Can I set a custom slug through the API?

    Yes, and it's free. Pass an alias field — 12 characters of letters, numbers, hyphens or underscores. Longer slugs are truncated to the first 12 characters rather than rejected, so read short_url back from the response. Taken aliases return HTTP 409; pre-check availability with GET /api/check-alias.

  • What options does /api/create support besides the URL?

    alias (custom slug), password (visitors must enter it before redirecting), max-clicks (link stops working after N clicks), expiration-time (ISO 8601 timestamp when the link dies), and description (a label of up to 100 characters shown on the stats page).

  • Is zip1.io a bit.ly API alternative?

    For programmatic link creation, yes. The bit.ly API needs an account and an OAuth token, and its free plan caps monthly link creation. zip1.io needs no token, has no monthly quota, and includes custom slugs, click caps, and password protection for free.

Ship your integration in five minutes

The full reference covers every endpoint, parameter, and response schema — or skip the reading and send your first request now.