# Create a link

`POST https://app.clik.so/api/links`

> **In short:** Makes a new short link that redirects to your destination URL. Only `destination_url` is required; leave out `short_code` and Clikso picks a random one.

## You need

* **API key permission:** `write`
* **Workspace role:** editor or higher
* **Plan:** some fields need a paid plan — see "Plan-gated fields" below.

## Example

```bash
curl -X POST "https://app.clik.so/api/links" \
  -H "Authorization: Bearer $CLIKSO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destination_url": "https://example.com/summer-sale",
    "short_code": "summer-sale",
    "title": "Summer sale",
    "folder_id": "6b7c8d9e-0f1a-4b2c-8d3e-4f5a6b7c8d9e",
    "tags": [
      "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
    ]
  }'
```

Response 201:

```json
{
  "status": 201,
  "success": true,
  "message": "Link created successfully",
  "data": {
    "id": "3f6c1a2e-9b4d-4e8f-a1c2-7d9e0f1a2b3c",
    "workspace_id": "8a1f2c3d-4b5e-4f60-9a7b-1c2d3e4f5a6b",
    "custom_domain_id": null,
    "domain": "clik.is",
    "domain_status": "default",
    "title": "Summer sale",
    "description": "",
    "short_code": "summer-sale",
    "destination_url": "https://example.com/summer-sale",
    "status": "active",
    "expires_at": null,
    "expired_redirect_url": null,
    "folder_id": "6b7c8d9e-0f1a-4b2c-8d3e-4f5a6b7c8d9e",
    "ab_testing": [],
    "geo_targeting": null,
    "device_targeting": null,
    "qr_metadata": null,
    "og_preview": null,
    "meta_pixel_id": null,
    "tiktok_pixel_id": null,
    "ga4_measurement_id": null,
    "gtm_container_id": null,
    "has_password": false,
    "click_count": 0,
    "created_by": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
    "created_at": "2026-10-09T09:30:00.000Z",
    "updated_at": "2026-10-09T09:30:00.000Z",
    "tags": [
      {
        "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "name": "launch",
        "color": "#3b82f6"
      }
    ],
    "creator": {
      "id": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
      "display_name": "Asha Rao",
      "email": "asha@example.com",
      "photo_url": ""
    }
  }
}
```

## Request body

| Field                       | Type                       | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| --------------------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `destination_url`           | string · uri               | yes      | Where the link sends visitors. Must start with `http://` or `https://`.                                                                                                                                                                                                                                                                                                                                                                                                  |
| `short_code`                | string                     | no       | Your own code: letters, digits and hyphens, 3–30 characters. On the Starter plan and up it may also use `/` for a nested code like `acme/launch`: at most 5 parts, no `/` at the start or end, no `//`, a letter or digit in every part, slashes counted in the 30. A `/` on Free gets `402 UPGRADE_REQUIRED`. Leave it out for a random 7-character code. 3–30 characters Pattern `^(?:[a-zA-Z0-9-]+\|-*[a-zA-Z0-9][a-zA-Z0-9-]*(?:/-*[a-zA-Z0-9][a-zA-Z0-9-]*){1,4})$` |
| `domain`                    | string                     | no       | `clik.is` or another free Clikso domain. For your own domain use `custom_domain_id`. Default `"clik.is"`                                                                                                                                                                                                                                                                                                                                                                 |
| `custom_domain_id`          | string · uuid              | no       | The id of one of your verified custom domains. Wins over `domain`.                                                                                                                                                                                                                                                                                                                                                                                                       |
| `title`                     | string                     | no       | A name for the link. Up to 60 characters                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `description`               | string                     | no       | A note about the link. Up to 250 characters                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `status`                    | string                     | no       | The starting status. One of: `active`, `archived`, `expired` Default `"active"`                                                                                                                                                                                                                                                                                                                                                                                          |
| `folder_id`                 | string · uuid              | no       | Put the link in this folder.                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `tags`                      | array of string · uuid     | no       | Ids of tags to attach.                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `password`                  | string or null             | no       | Visitors must type this before they are redirected. Starter plan and up. Up to 100 characters                                                                                                                                                                                                                                                                                                                                                                            |
| `expires_at`                | string · date-time or null | no       | When the link stops working (ISO 8601).                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `expired_redirect_url`      | string · uri or null       | no       | Where visitors go after the link expires.                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ab_testing`                | array of ABVariant         | no       | Split visitors between several destinations. Pro plan and up.                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ab_testing[].url`          | string · uri               | yes      | Where this share of visitors goes.                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `ab_testing[].percentage`   | integer                    | yes      | This variant's weight. Weights are relative, so they do not have to add up to 100. 0–100                                                                                                                                                                                                                                                                                                                                                                                 |
| `geo_targeting`             | GeoTargeting               | no       | Destination per country. Keys are 2-letter country codes in capitals (`US`, `IN`); values are URLs.                                                                                                                                                                                                                                                                                                                                                                      |
| `device_targeting`          | DeviceTargeting            | no       | Destination per device. Only `ios`, `android` and `desktop` take effect; `macos` and `linux` are stored but not used.                                                                                                                                                                                                                                                                                                                                                    |
| `device_targeting.ios`      | string · uri               | no       | For iPhone and iPad visitors.                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `device_targeting.android`  | string · uri               | no       | For Android visitors.                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `device_targeting.desktop`  | string · uri               | no       | For visitors not on a phone or tablet.                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `device_targeting.macos`    | string · uri               | no       | Stored, but not used when redirecting.                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `device_targeting.linux`    | string · uri               | no       | Stored, but not used when redirecting.                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `og_preview`                | OgPreview                  | no       | The title, description and image social apps show for the short link. Starter plan and up.                                                                                                                                                                                                                                                                                                                                                                               |
| `og_preview.og_title`       | string                     | no       | The preview title.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `og_preview.og_description` | string                     | no       | The preview description.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `og_preview.og_image_url`   | string · uri               | no       | URL of the preview image.                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `qr_metadata`               | QrMetadata                 | no       | Saved QR code style. Clikso does not generate QR images through the API.                                                                                                                                                                                                                                                                                                                                                                                                 |
| `qr_metadata.color`         | string                     | no       | QR colour.                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `qr_metadata.shape`         | string                     | no       | QR dot shape.                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `qr_metadata.logo_url`      | string                     | no       | URL of a logo for the QR centre.                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `qr_metadata.params`        | object                     | no       | Other QR settings.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `meta_pixel_id`             | string or null             | no       | Meta Pixel id: 6–20 digits. Starter plan and up. Pattern `^\d{6,20}$`                                                                                                                                                                                                                                                                                                                                                                                                    |
| `tiktok_pixel_id`           | string or null             | no       | TikTok Pixel id: 8–40 letters and digits. Starter plan and up. Pattern `^[A-Za-z0-9]{8,40}$`                                                                                                                                                                                                                                                                                                                                                                             |
| `ga4_measurement_id`        | string or null             | no       | GA4 measurement id, like `G-ABC123XYZ`. Starter plan and up. Pattern `^G-[A-Z0-9]{4,16}$`                                                                                                                                                                                                                                                                                                                                                                                |
| `gtm_container_id`          | string or null             | no       | Google Tag Manager container id, like `GTM-ABC1234`. Starter plan and up. Pattern `^GTM-[A-Z0-9]{4,12}$`                                                                                                                                                                                                                                                                                                                                                                 |

## Plan-gated fields

| Field                | Feature            | Lowest plan |
| -------------------- | ------------------ | ----------- |
| `password`           | passwordProtection | Starter     |
| `og_preview`         | customOgTags       | Starter     |
| `meta_pixel_id`      | trackingPixels     | Starter     |
| `tiktok_pixel_id`    | trackingPixels     | Starter     |
| `ga4_measurement_id` | trackingPixels     | Starter     |
| `gtm_container_id`   | trackingPixels     | Starter     |
| `geo_targeting`      | geoTargeting       | Pro         |
| `device_targeting`   | deviceTargeting    | Pro         |
| `ab_testing`         | abTesting          | Pro         |
| `short_code`         | nestedSlugs        | Starter     |

## Common errors

| Status | Code                  | When                                                                                                                                                                                                                                                                                                            |
| ------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401    | `UNAUTHORIZED`        | The API key is missing, malformed or unknown.                                                                                                                                                                                                                                                                   |
| 402    | `UPGRADE_REQUIRED`    | You set a field your plan does not include, such as `geo_targeting` on Free, or a `short_code` with a `/` on Free. `details` names the field and the plan you need.                                                                                                                                             |
| 403    | `FORBIDDEN`           | The key only has Read permission, or its creator is a viewer in this workspace.                                                                                                                                                                                                                                 |
| 404    | `NOT_FOUND`           | `custom_domain_id` is not one of this workspace's domains.                                                                                                                                                                                                                                                      |
| 409    | `CONFLICT`            | Another link already uses this `short_code` on this domain, or it is a reserved name on a Clikso domain.                                                                                                                                                                                                        |
| 422    | `VALIDATION_ERROR`    | A field is missing or malformed (for example a `title` over 60 characters, a `description` over 250, or an `expires_at` that is not a date — `details.field` names it; a bad `short_code` is named in `details.short_code`), the custom domain is not verified, or a folder or tag id is not in this workspace. |
| 422    | `DESTINATION_BLOCKED` | A URL in the body points at a link shortener or a blocked site. `error.message` says which one.                                                                                                                                                                                                                 |
| 429    | `USAGE_LIMIT_REACHED` | You have created your plan's monthly number of links.                                                                                                                                                                                                                                                           |
| 429    | `RATE_LIMITED`        | The key went over its per-minute request limit.                                                                                                                                                                                                                                                                 |

## Good to know

* The API does not return a ready-made short URL. Build it yourself: `https://{domain}/{short_code}`.
* `short_code` may use letters, digits and hyphens, 3 to 30 characters (it was 20 before 1.64.0). Underscores and dots are refused. Leave it out and you get a random 7-character code.
* On the Starter plan and up, `short_code` may also use `/` to make a nested code like `acme/launch` (the short URL is `https://clik.is/acme/launch`). At most 5 parts (4 slashes), no `/` at the start or end, no `//`, and each part needs a letter or digit. The slashes count toward the 30 characters. On Free a `/` gets `402 UPGRADE_REQUIRED`.
* A bad `short_code` gets `422 VALIDATION_ERROR` saying what is wrong in plain English, for example `short_code: Use one slash (/) at a time, not two.` — the same sentence is in `details.short_code`.
* On `clik.is` (and the other Clikso domains) some official-sounding names are reserved, such as `pricing` or `login`, and so is any nested code that starts with one (`pricing/2026`). They are refused like a taken code (`409`). Your own custom domain has no reserved names.
* `domain` only accepts `clik.is` or one of Clikso's free domains (see [List free Clikso domains](https://clik.so/docs/api/domains/list-system-domains)). For your own domain, send its id as `custom_domain_id`; it must be verified.
* Keep `title` to 60 characters and `description` to 250. `password` can be up to 100 characters and is never returned — you only see `has_password`.
* `expires_at` must be a date (ISO 8601, for example `2026-12-31T23:59:00Z`) and `expired_redirect_url` at most 2048 characters. A bad value gets `422 VALIDATION_ERROR` with `details.field` naming the field.
* Every URL in the body is checked: `destination_url`, `expired_redirect_url`, and each A/B, country and device URL. A link shortener or a blocked site is refused with `DESTINATION_BLOCKED`.
* Each new link counts toward your plan's monthly link limit (Free 50, Starter 500, Pro 5,000, Business 10,000). Over it, you get `429 USAGE_LIMIT_REACHED`.
* There is no bulk create. Send one request per link.
* Rule order at the edge: country rules first, then device rules (which win over country), and A/B variants only when neither matched. Only the `ios`, `android` and `desktop` device rules take effect.

---

Source: https://clik.so/docs/api/links/create-link
