> ## Documentation Index
> Fetch the complete documentation index at: https://shortpen.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit Link

> Updates an existing link identified by `url_id`. Only `url_id` is required — include at least one additional field to specify what to change. Omitted fields retain their current values. The API enforces the same plan limits and feature checks as creation.

Update an existing link by supplying its `url_id` along with only the fields you want to change. Omitted fields retain their current values, so you can make targeted updates without resending the entire link configuration.

<Tip>
  You can find the `url_id` of any link by calling [`GET /v1/links`](./list-links) — the `id` field in each item is the value you need.
</Tip>

### How it works

Only `url_id` is strictly required. You must also include **at least one additional field** to specify what to change — otherwise the API returns a `400` error.

The edit endpoint shares the same internal logic as creation. When `url_id` is present in the request, the API locates the existing link and applies the supplied fields as an update. Any field you omit is preserved from the existing link, including settings like redirect type, password protection, cloaking, tracking, and social previews.

Both `PUT` and `PATCH` methods are accepted and behave identically.

### Request body

| Field                      | Type                               | Required | Description                                                                                |
| -------------------------- | ---------------------------------- | -------- | ------------------------------------------------------------------------------------------ |
| `url_id`                   | integer                            | ✅        | ID of the link to update.                                                                  |
| `url`                      | string (URI)                       |          | New destination URL.                                                                       |
| `domain_id`                | integer                            |          | Domain that hosts the link. Must be active for the organization.                           |
| `workspace_id`             | integer                            |          | Overrides the default workspace.                                                           |
| `title`                    | string                             |          | Human-friendly title for the link.                                                         |
| `custom_slug`              | string                             |          | Branded slug. Plan limits and reserved-word checks apply.                                  |
| `folder_id`                | integer                            |          | Assigns the link to a folder.                                                              |
| `param`                    | object                             |          | Query parameters appended to the destination URL (e.g. UTM tags).                          |
| `generate_qr`              | boolean                            |          | Generates or regenerates a QR code for the link.                                           |
| `enable_tracking`          | boolean                            |          | Associates the link with a tracking pixel. Requires `pixel_id`.                            |
| `pixel_id`                 | integer                            |          | Pixel identifier for event tracking.                                                       |
| `redirect_type`            | integer (301 or 302)               |          | HTTP redirect status.                                                                      |
| `link_cloak`               | boolean                            |          | Cloaks the destination URL.                                                                |
| `hide_referer`             | boolean                            |          | Removes the referrer header.                                                               |
| `with_password`            | boolean                            |          | Enables password protection. Pair with `url_password`.                                     |
| `url_password`             | string                             |          | Password required to access the link.                                                      |
| `r`, `g`, `b`              | integer (0-255)                    |          | RGB color channels for QR codes.                                                           |
| `uploaded_logo_type`       | enum(`none`, `custom`, `uploaded`) |          | Logo embedded in QR codes.                                                                 |
| `uploaded_logo_data`       | base64 string                      |          | Custom logo image when `uploaded_logo_type` is `uploaded`.                                 |
| `social_share_title`       | string                             |          | Overrides the OpenGraph title.                                                             |
| `social_share_description` | string                             |          | Overrides the OpenGraph description.                                                       |
| `social_share_image_data`  | base64 string                      |          | Custom social preview image.                                                               |
| `tag_ids`                  | integer\[]                         |          | Replaces the link's tags with the supplied set. See [Updating tags](#updating-tags) below. |
| `notes`                    | string                             |          | Edit the custom note of the link. 300 characters max.                                      |

### Updating tags

The `tag_ids` field follows the same "only what you send" rule as the rest of the edit endpoint, with one nuance worth calling out:

* **Omit `tag_ids`** — the link's existing tags are left untouched.
* **Send an array of IDs** — the link's tags are replaced with exactly that set (`[12, 18]` keeps only tags 12 and 18).
* **Send an empty array `[]`** — every tag is removed from the link.

Tags must belong to the same workspace and organization as the link; unknown IDs are silently ignored. A JSON-encoded string such as `"[12,18]"` is also accepted.

### Response highlights

* `data.link` — the fully qualified link after the update.
* `data.short_url` — same value as `link`. **Deprecated** — will be removed in a future version; migrate to `data.link`.
* `data.qr` — base64-encoded QR PNG when a QR code exists; otherwise `null`.
* `data.created` — always `false` for edit operations, confirming the link was updated rather than newly created.

### Error handling

| Status | Meaning                                                                     |
| ------ | --------------------------------------------------------------------------- |
| 400    | Validation error — `url_id` is missing, or no field to update was provided. |
| 401    | Missing or invalid API token.                                               |
| 404    | No link found for the given `url_id` in the authenticated organization.     |
| 429    | A monthly feature quota has been reached (e.g. QR codes, custom slugs).     |
| 500    | Unexpected error while updating the link. Retry the request.                |


## OpenAPI

````yaml PUT /v1/links
openapi: 3.1.0
info:
  title: ShortPen API
  version: 1.0.0
  description: >-
    Create branded links, fetch organization resources, and pull analytics
    programmatically with the ShortPen REST API.
servers:
  - url: https://{environment}.shortpen.com
    description: ShortPen API host
    variables:
      environment:
        default: api
        enum:
          - api
          - staging-api
security: []
tags:
  - name: Core
    description: Utility endpoints for checking service health.
  - name: Authentication
    description: Endpoints that return identity, limits, and feature availability.
  - name: Links
    description: Create, edit, and list links and their auxiliary assets like QR codes.
  - name: Resources
    description: >-
      Lookup supporting entities such as domains, workspaces, folders, and
      pixels.
  - name: Analytics
    description: Retrieve click analytics and raw tracking events.
paths:
  /v1/links:
    put:
      tags:
        - Links
      summary: Edit a link
      description: >-
        Updates an existing link identified by `url_id`. Only `url_id` is
        required — include at least one additional field to specify what to
        change. Omitted fields retain their current values. The API enforces the
        same plan limits and feature checks as creation.
      operationId: editLink
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditLinkRequest'
            examples:
              changeDestination:
                summary: Update destination URL
                value:
                  url_id: 501
                  url: https://example.com/new-destination
                  domain_id: 1
              fullUpdate:
                summary: Update multiple properties
                value:
                  url_id: 501
                  url: https://example.com/updated-campaign
                  domain_id: 3
                  workspace_id: 24
                  title: Updated campaign link
                  custom_slug: summer-2026
                  redirect_type: 302
                  enable_tracking: true
                  pixel_id: 12
                  param:
                    utm_source: social
                    utm_medium: post
                    utm_campaign: summer-relaunch
      responses:
        '200':
          description: Link updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinkResponse'
        '400':
          description: Validation error or invalid domain
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Monthly link or feature limit reached
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    EditLinkRequest:
      allOf:
        - type: object
          properties:
            url_id:
              type: integer
              description: >-
                ID of the existing link to update. Retrieve this from the List
                Links endpoint or the link creation response.
          required:
            - url_id
        - $ref: '#/components/schemas/LinkFieldsMixin'
      required:
        - url_id
      description: >-
        Only `url_id` is required. At least one additional field must be
        provided to specify what to change. Omitted fields retain their current
        values.
    LinkResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        status_code:
          type: integer
          example: 200
        message:
          type: string
          example: ''
        data:
          $ref: '#/components/schemas/LinkData'
      required:
        - success
        - status_code
        - data
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        status_code:
          type: integer
          example: 401
        message:
          type: string
          example: There was an error while processing your request.
        data:
          description: Optional payload returned for additional context.
          nullable: true
      required:
        - success
        - status_code
        - message
    LinkFieldsMixin:
      type: object
      description: Common fields shared between link creation and editing.
      properties:
        url:
          type: string
          format: uri
          description: Destination URL the link redirects to.
          example: https://example.com/launch
        domain_id:
          type: integer
          description: ID of the domain that hosts the link.
        workspace_id:
          type: integer
          description: >-
            Workspace ID. Defaults to the first workspace associated with the
            organization when omitted.
        title:
          type: string
          description: Optional human-friendly title for the link.
        custom_slug:
          type: string
          description: >-
            Custom slug appended to the domain instead of an auto-generated
            code.
        folder_id:
          type: integer
          description: Folder to assign the link to.
        param:
          type: object
          description: Query parameters appended to the destination URL.
          additionalProperties:
            type: string
        generate_qr:
          type: boolean
          description: Whether to create a QR code for the link.
          default: false
        enable_tracking:
          type: boolean
          description: >-
            Set to true to associate the link with the specified pixel for event
            tracking.
          default: false
        pixel_id:
          type: integer
          description: Pixel ID used when tracking is enabled.
        redirect_type:
          type: integer
          enum:
            - 301
            - 302
          description: HTTP redirect status applied when visitors follow the link.
          default: 301
        link_cloak:
          type: boolean
          description: If true, cloaks the destination URL.
        hide_referer:
          type: boolean
          description: If true, removes the referrer header for visitors.
        with_password:
          type: boolean
          description: Protects the link behind a password.
        url_password:
          type: string
          description: Password required when `with_password` is true.
        r:
          type: integer
          minimum: 0
          maximum: 255
          description: Red channel used when generating QR codes.
          example: 45
        g:
          type: integer
          minimum: 0
          maximum: 255
          description: Green channel used when generating QR codes.
          example: 151
        b:
          type: integer
          minimum: 0
          maximum: 255
          description: Blue channel used when generating QR codes.
          example: 123
        uploaded_logo_type:
          type: string
          description: Controls which logo is embedded inside generated QR codes.
          enum:
            - none
            - custom
            - uploaded
          default: none
        uploaded_logo_data:
          type: string
          format: byte
          description: Base64-encoded file used when `uploaded_logo_type` is `uploaded`.
        social_share_title:
          type: string
          description: Overrides the title shown in social previews.
        social_share_description:
          type: string
          description: Overrides the description shown in social previews.
        social_share_image_data:
          type: string
          format: byte
          description: Base64-encoded image used for the social preview.
        tag_ids:
          type: array
          items:
            type: integer
          description: >-
            IDs of the tags to associate with the link. On creation the listed
            tags are attached. On edit, sending this field replaces the link's
            tags with the supplied set — an empty array clears every tag, while
            omitting the field entirely leaves existing tags untouched. Tags
            must belong to the same workspace and organization; unknown IDs are
            ignored. A JSON-encoded string of IDs (e.g. "[12,18]") is also
            accepted for backwards compatibility.
          example:
            - 12
            - 18
        notes:
          type: string
          description: Overrides the private notes shown in ShortPen Links/QRs list.
    LinkData:
      type: object
      properties:
        link:
          type: string
          format: uri
          description: Fully qualified link combining the selected domain and slug.
          example: https://go.shortpen.com/summer-2025
        short_url:
          type: string
          format: uri
          description: >-
            Deprecated — use `link` instead. Will be removed in a future
            version.
          example: https://go.shortpen.com/summer-2025
          deprecated: true
        qr:
          type: string
          nullable: true
          description: Base64-encoded PNG image for the generated QR code.
        created:
          type: boolean
          description: >-
            `true` when a new link was created, `false` when an existing link
            was updated.
      required:
        - link
        - short_url
        - created
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Personal Access Token

````