Reurl API

Base URL: https://api.reurl.to/v1. Generate account API tokens in the dashboard at https://app.reurl.to.

The unversioned paths remain available as compatibility aliases. New integrations should use /v1.

Authentication

Business APIs accept an API token through the standard Authorization header.

Authorization: Bearer reurl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Browser dashboard requests can also use the session cookie created by email-code or GitHub login. Account token management endpoints require that browser session. API tokens cannot manage other API tokens.

API layout

/v1/links owns short-link resources. /v1/qr owns QR generation and downloads. /v1/geoip owns IP and domain lookup. Each resource keeps one purpose and uses the same JSON envelope; short-link redirects remain on https://reurl.to/:code and do not show an ad or delay page.

Response format

All JSON tool APIs return the same envelope. The resource payload stays small and predictable under data:

OperationResponse shape
List links{ "code": 200, "msg": "ok", "data": { "links": [...] } }
Create link{ "code": 201, "msg": "created", "data": { "link": {...}, "short_url": "https://reurl.to/code" } }
Read or update link{ "code": 200, "msg": "ok", "data": { "link": {...} } }
Delete link{ "code": 200, "msg": "ok", "data": { "deleted": true } }
Short-link QR asset{ "code": 201, "msg": "created", "data": { "qr_code": {...} } }
Standalone QR generation{ "code": 200, "msg": "ok", "data": { "qr_code": {...} } }
IP/domain lookup service{ "code": 200, "msg": "ok", "data": { "country": {...}, "asn": {...}, "city": {...} } }
List tokens{ "code": 200, "msg": "ok", "data": { "tokens": [...], "limit": 5 } }
Create token{ "code": 201, "msg": "created", "data": { "token": "reurl_..." } }
Delete token{ "code": 200, "msg": "ok", "data": { "deleted": true } }

Errors use the same envelope:

{
  "code": 401,
  "msg": "Authentication is required.",
  "data": null,
}

Direct file outputs are the exception: short-link QR SVG and QR download URLs return image bytes when successful, while their errors still use the JSON envelope.

Access policy

Short-link, QR, GeoIP, analytics, and other business APIs do not apply server-side rate limits or business quotas. An API token only authenticates the account and identifies the resource owner. Each account can keep at most 5 active API tokens.

Token management itself requires a browser session. Email verification still has anti-abuse protection because it is an authentication security control, not a business quota.

Account tokens

Token management requires a browser session from email-code or GitHub login. Deleting a token permanently removes it; deleted tokens cannot be restored or used again.

GET /v1/tokens
POST /v1/tokens
DELETE /v1/tokens/:id

List links:

curl https://api.reurl.to/v1/links \
  -H "Authorization: Bearer reurl_xxx"

Create a link with JSON:

curl -X POST https://api.reurl.to/v1/links \
  -H "Authorization: Bearer reurl_xxx" \
  -H "Content-Type: application/json" \
  -d '{"target_url":"https://example.com","code":"launch"}'

Update status or metadata:

curl -X PATCH https://api.reurl.to/v1/links/LINK_ID \
  -H "Authorization: Bearer reurl_xxx" \
  -H "Content-Type: application/json" \
  -d '{"is_active":false}'

Delete a link:

curl -X DELETE https://api.reurl.to/v1/links/LINK_ID \
  -H "Authorization: Bearer reurl_xxx"

Short-link QR endpoints belong to the short-link API. They call the QR generation service with the short URL as input.

curl https://api.reurl.to/v1/links/LINK_ID/qr \
  -H "Authorization: Bearer reurl_xxx"

The response is image bytes. Use the standalone QR API below when the input is arbitrary text instead of a short link.

Save a short-link QR asset:

curl -X POST https://api.reurl.to/v1/links/LINK_ID/qr \
  -H "Authorization: Bearer reurl_xxx" \
  -H "Content-Type: application/json" \
  -d '{"persist":true,"format":"svg"}'

Response:

{
  "code": 201,
  "msg": "created",
  "data": {
    "qr_code": {
      "key": "qr/launch.svg",
      "format": "svg",
      "short_url": "https://reurl.to/launch"
    }
  }
}

Standalone QR generation

Generate a QR code from arbitrary text. The default response is JSON with inline SVG at data.qr_code.svg.

curl -X POST https://api.reurl.to/v1/qr/text \
  -H "Authorization: Bearer reurl_xxx" \
  -H "Content-Type: application/json" \
  -d '{"text":"https://example.com","format":"svg"}'

Request a short-lived download:

curl -X POST https://api.reurl.to/v1/qr/text \
  -H "Authorization: Bearer reurl_xxx" \
  -H "Content-Type: application/json" \
  -d '{"text":"launch code","format":"svg","download":true}'

Response:

{
  "code": 201,
  "msg": "created",
  "data": {
    "qr_code": {
      "format": "svg",
      "content_type": "image/svg+xml; charset=utf-8",
      "download_url": "https://api.reurl.to/v1/qr/download/abc123",
      "expires_at": "2026-07-26T12:07:00.000Z",
      "expires_in_seconds": 420
    }
  }
}

Download URLs expire after 7 minutes. Expired artifacts are removed when accessed after expiry and are also removed by scheduled cleanup.

Standalone QR formats are svg and png. SVG responses include inline SVG text; PNG responses include base64 image bytes, and download:true returns a 7-minute download URL.

IP and domain lookup

Direct API lookup requests require a token. The public homepage lookup form can be used without pasting a token and returns both a text summary and JSON. Business calls do not have a server-side quota or rate limit.

Combined lookup:

curl "https://api.reurl.to/v1/geoip/lookup?ip=8.8.8.8&lang=en" \
  -H "Authorization: Bearer reurl_xxx"

Specific lookup:

curl "https://api.reurl.to/v1/geoip/country?ip=1.1.1.1&lang=en" \
  -H "Authorization: Bearer reurl_xxx" \
curl "https://api.reurl.to/v1/geoip/asn?ip=1.1.1.1&lang=en" \
  -H "Authorization: Bearer reurl_xxx" \
curl "https://api.reurl.to/v1/geoip/city?ip=1.1.1.1&lang=en" \
  -H "Authorization: Bearer reurl_xxx"

Domain lookup:

curl -X POST https://api.reurl.to/v1/geoip/lookup \
  -H "Authorization: Bearer reurl_xxx" \
  -H "Content-Type: application/json" \
  -d '{"input":"example.com"}'

Representative response:

{
  "code": 200,
  "msg": "ok",
  "data": {
    "ip": "1.1.1.1",
    "lang": "en",
    "country": { "countryCode": "AU", "countryName": "Australia" },
    "asn": { "autonomousSystemNumber": 13335, "autonomousSystemOrganization": "Example Network" },
    "city": { "countryCode": "AU", "city": "Sydney", "timezone": "Australia/Sydney" }
  }
}

The active dataset is versioned and promoted only after validation. If a refresh fails, the previous active version keeps serving.

Geolocation is dataset-based and best-effort. It is not a street-address result and must not be treated as a precise user identity signal.

Token management

Token management requires dashboard session login. These endpoints do not accept API tokens.

List tokens:

curl https://api.reurl.to/v1/tokens \
  -H "Cookie: reurl_session=..."

Create token:

curl -X POST https://api.reurl.to/v1/tokens \
  -H "Cookie: reurl_session=..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Production"}'

Delete token:

curl -X DELETE https://api.reurl.to/v1/tokens/TOKEN_ID \
  -H "Cookie: reurl_session=..."

Login protection

Email-code login can require a browser challenge when TURNSTILE_SECRET is configured on the backend. The backend verifies the token before sending email.