engineeringJul 1, 2026

Getting Started With the Shortly API: Authentication, Endpoints, and Best Practices

Create an API key, make your first request, and learn the patterns that keep a link-shortening integration reliable in production.

If you generate links programmatically — one per order confirmation, one per support ticket, one per user invite — doing it by hand stops working almost immediately. The Shortly API lets you create and manage short links from your own code.

This guide covers authentication, the core endpoints, error handling, and the practical patterns that separate a demo integration from one that survives production traffic.

Before you start

You need two things:

  1. A Shortly account.
  2. An API key, created from the API keys section of your dashboard.

An API key is shown once, at creation time. Copy it immediately and store it in your secret manager or environment variables. If you lose it, revoke it and create a new one — there is no way to display an existing key again, which is deliberate.

Authentication

Every request carries the key in an Authorization header using the bearer scheme.

Authorization: Bearer sk_live_your_key_here

A missing or invalid key returns 401 Unauthorized. A valid key belonging to a different workspace than the resource you requested returns 404 Not Found rather than 403, so that resource IDs cannot be enumerated by probing.

Never put an API key in frontend code. Anything shipped to a browser or a mobile binary is public, no matter how it is obfuscated. Call the API from your server, and expose your own endpoint to the client if the browser needs to trigger link creation.

Creating your first short link

A minimal creation request needs only a destination URL.

POST /api/public/v1/links
Content-Type: application/json
Authorization: Bearer sk_live_your_key_here

{
  "url": "https://example.com/spring-sale?utm_source=email&utm_medium=newsletter"
}

The response contains the generated slug and the full short URL:

{
  "id": "0d0f8a2e-...",
  "slug": "a7Kd2q",
  "short_url": "https://getswiftlink.world/a7Kd2q",
  "url": "https://example.com/spring-sale?utm_source=email&utm_medium=newsletter",
  "created_at": "2026-08-16T09:14:22.104Z"
}

Store the id on your side, not just the short URL. The ID is what you use for updates, analytics lookups, and deletion.

Requesting a custom slug

Pass a slug to control the short path yourself.

{
  "url": "https://example.com/pricing",
  "slug": "pricing-2026"
}

Slugs are unique per domain. If the slug is taken you get 409 Conflict, and your code should either retry with a different value or surface the collision to the user. Do not retry the same slug in a loop.

Good slug rules for generated links:

  • Lowercase only. Mixed case gets mistyped and looks wrong in print.
  • Avoid characters that are ambiguous when read aloud or printed: l, 1, I, O, 0.
  • Keep them under about 12 characters if a human will ever type one.
  • Never encode anything sensitive. A slug is public the moment it is created.

Updating and deleting links

Update the destination without changing the short URL:

PATCH /api/public/v1/links/{id}
{
  "url": "https://example.com/summer-sale"
}

This is the single most valuable property of a short link. Anything already printed, posted, or emailed keeps working and now points somewhere new.

Deletion is available but should be rare:

DELETE /api/public/v1/links/{id}

Once deleted, the slug returns a 404 for everyone who ever received it, including recipients of printed material. Prefer repointing a link at a "this campaign has ended" page over deleting it.

Handling errors properly

The API uses conventional HTTP status codes. Handle each class differently.

StatusMeaningCorrect response in your code
400Malformed body or invalid URLFix the request; do not retry
401Missing or invalid API keyAlert; do not retry
404Resource not found or not yoursTreat as gone; do not retry
409Slug already in useGenerate a new slug and retry once
429Rate limit exceededBack off exponentially and retry
5xxServer-side problemRetry with backoff, then queue

The rule that matters: retry only 429 and 5xx. Retrying a 400 in a loop turns a small bug into an outage of your own making.

Rate limits and backoff

Limits are applied per API key. When you exceed one, the API returns 429 and your client should wait before trying again — starting at roughly one second and doubling each attempt, with a small random jitter so that a fleet of workers does not retry in lockstep.

For bulk work, do not fire hundreds of parallel requests. Push the jobs onto a queue and process them with a small, bounded concurrency — four to eight workers is usually plenty and will finish faster than an unbounded burst that spends its time being throttled.

Idempotency: avoid duplicate links

The API creates a new link on every successful POST. If your job retries after a network timeout, you can end up with two short links for the same destination.

Guard against this on your side:

  1. Keep a table mapping your own entity — order ID, ticket ID, user ID — to the returned link ID.
  2. Before creating, check whether a link already exists for that entity.
  3. Write the mapping row in the same transaction that records the successful API call.

This is a few lines of code and it eliminates an entire class of confusing duplicate-link bugs.

Adding UTM parameters

Add campaign parameters to the destination URL before you send it, not afterwards. The short link stores whatever destination you give it, so the parameters travel with every click.

https://example.com/checkout
  ?utm_source=app
  &utm_medium=email
  &utm_campaign=order-confirmation

Keep the values lowercase and consistent across every integration. If one service writes Email and another writes email, your analytics tool will report them as two separate channels forever. If your team has not agreed on conventions yet, settle that first — the complete guide to UTM parameters covers the naming rules worth adopting.

Security checklist before you ship

  • API key stored in a secret manager or environment variable, never in source control.
  • Requests made server-side only.
  • A separate key per environment, so revoking staging does not break production.
  • Keys rotated on a schedule and immediately when someone with access leaves.
  • Destination URLs validated before submission — reject anything that is not http or https, and be careful about accepting user-supplied URLs without a review step, since an open redirect on your domain is a phishing vector.
  • Logs that record the link ID but not the API key.

A realistic first integration

The smallest useful integration looks like this:

  1. Add SHORTLY_API_KEY to your environment.
  2. Write one function, createShortLink(url, slug?), that wraps the POST and throws typed errors.
  3. Add a mapping table from your entity to the link ID.
  4. Call it from one place — order confirmations are a good first candidate.
  5. Add retry with backoff for 429 and 5xx only.
  6. Check the analytics after a week to confirm real clicks are arriving.

Ship that, then expand. Trying to build a generic link service before you have a single caller is how integrations end up half-finished.

Next steps

Create a key in the API keys section of your dashboard and make your first request. If you need to move an existing set of links across, the bulk import tool handles up to 500 rows at a time without touching the API at all — and for one-off links, the free link shortener is faster than writing code.

Get link tips in your inbox

Join founders, marketers, and creators who receive weekly growth ideas for short links, QR codes, and analytics.

No spam. Unsubscribe anytime.