> ## 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.

# Create Link

> Creates a new link in the current workspace. The API enforces plan limits and feature availability for the authenticated organization.

Create a new link inside the workspace tied to your API token. The endpoint shares logic with the dashboard, so all plan limits, QR quotas, and custom domain validations apply here too.

<Tip>
  `domain_id` must point to a domain that is active for the organization and visible to the authenticated workspace. Use [`POST /v1/get`](./get-resources) with `resource: "domain"` to retrieve the allowed IDs.
</Tip>

### Request body

| Field                      | Type                               | Required | Description                                                                                                                                                                              |
| -------------------------- | ---------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`                      | string (URI)                       | ✅        | Destination URL. Missing schemes are automatically prefixed with `https://`.                                                                                                             |
| `domain_id`                | integer                            | ✅        | Domain that will host the link. The API validates ownership and plan eligibility.                                                                                                        |
| `workspace_id`             | integer                            |          | Overrides the default workspace inferred from the token. Useful when a key has access to multiple workspaces.                                                                            |
| `title`                    | string                             |          | Optional human-friendly title for reporting.                                                                                                                                             |
| `custom_slug`              | string                             |          | Branded slug appended to the domain instead of an auto-generated code. Plan limits and reserved-word checks apply.                                                                       |
| `folder_id`                | integer                            |          | Assigns the link to an existing folder.                                                                                                                                                  |
| `param`                    | object                             |          | Additional query parameters appended to the destination URL (for example UTM tags). Empty values are stripped automatically.                                                             |
| `generate_qr`              | boolean                            |          | Generates and returns a base64-encoded QR code alongside the link.                                                                                                                       |
| `enable_tracking`          | boolean                            |          | Links the URL to a tracking pixel. Requires `pixel_id`.                                                                                                                                  |
| `pixel_id`                 | integer                            |          | Pixel identifier retrieved via the resources endpoint.                                                                                                                                   |
| `redirect_type`            | integer (301 or 302)               |          | Controls whether redirects are permanent or temporary. Defaults to `301`.                                                                                                                |
| `link_cloak`               | boolean                            |          | Cloaks the destination URL.                                                                                                                                                              |
| `hide_referer`             | boolean                            |          | Removes the referrer header so destination sites do not see the original source.                                                                                                         |
| `with_password`            | boolean                            |          | Protects the link behind a password. Pair with `url_password`.                                                                                                                           |
| `url_password`             | string                             |          | Password required to resolve the link when `with_password` is true.                                                                                                                      |
| `r`, `g`, `b`              | integer (0-255)                    |          | RGB color channels used when a QR code is generated.                                                                                                                                     |
| `uploaded_logo_type`       | enum(`none`, `custom`, `uploaded`) |          | Controls the logo embedded inside generated QR codes. `custom` reuses the organization logo, `uploaded` expects `uploaded_logo_data`.                                                    |
| `uploaded_logo_data`       | base64 string                      |          | Base64-encoded image used for the QR logo when `uploaded_logo_type` is `uploaded`.                                                                                                       |
| `social_share_title`       | string                             |          | Overrides the OpenGraph title used when the link is shared.                                                                                                                              |
| `social_share_description` | string                             |          | Overrides the OpenGraph description.                                                                                                                                                     |
| `social_share_image_data`  | base64 string                      |          | Custom social preview image (PNG/JPEG/SVG).                                                                                                                                              |
| `tag_ids`                  | integer\[]                         |          | IDs of the tags to attach to the new link. Tags must belong to the same workspace and organization; unknown IDs are ignored. A JSON-encoded string such as `"[12,18]"` is also accepted. |
| `notes`                    | string                             |          | Add a custom note to the new link. 300 characters max.                                                                                                                                   |

> Need to attach a stored social preview image that already lives on ShortPen? Set `social_share_image_data` to the base64 payload provided by previous uploads or send the legacy `social_share_image_session` value.

### Response highlights

* `data.link` — fully qualified link combining the selected domain and slug.
* `data.short_url` — same value as `link`. **Deprecated** — will be removed in a future version; migrate to `data.link`.
* `data.qr` — base64-encoded PNG when `generate_qr` evaluates to true; otherwise `null`.
* `data.created` — `true` for newly created links.

If a monthly quota (links, QR codes, custom slugs, etc.) has been reached, the API responds with HTTP 429 and a descriptive `message` so you can trigger a plan upgrade workflow or notify an operator.

<Note>
  Need to update an existing link instead? Use the [Edit Link](./edit-link) endpoint with `PUT` or `PATCH /v1/links`.
</Note>


## OpenAPI

````yaml POST /v1/generate
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/generate:
    post:
      tags:
        - Links
      summary: Create a link
      description: >-
        Creates a new link in the current workspace. The API enforces plan
        limits and feature availability for the authenticated organization.
      operationId: createLink
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateLinkRequest'
            examples:
              basic:
                summary: Basic link
                value:
                  url: https://example.com/launch
                  domain_id: 1
                  workspace_id: 24
                  title: Launch landing page
              withCustomizations:
                summary: Custom slug, QR, and tracking
                value:
                  url: https://example.com/summer-campaign
                  domain_id: 3
                  workspace_id: 24
                  custom_slug: summer-2025
                  generate_qr: true
                  enable_tracking: true
                  pixel_id: 12
                  param:
                    utm_source: newsletter
                    utm_medium: email
                    utm_campaign: summer-launch
      responses:
        '200':
          description: Link created 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:
    CreateLinkRequest:
      allOf:
        - $ref: '#/components/schemas/LinkFieldsMixin'
      required:
        - url
        - domain_id
    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

````