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

# Upsert shortcut

> Creates a shortcut at the given slug, or updates the existing one. Returns `201` when a new shortcut is created and `200` when an existing one is updated. The handle is taken verbatim as the slug — for symmetry with `GET`/`PATCH`/`DELETE` the segment is named `{handle}`, but PUT does not resolve UUID-shaped handles to a row's ID. One guardrail: a UUID-shaped handle that collides with an existing shortcut's `id` returns `400 validation_error` (use `PATCH /v1/shortcuts/{handle}` to update by ID); UUID-shaped slugs that don't collide are accepted as slugs.



## OpenAPI

````yaml /openapi.json put /v1/shortcuts/{handle}
openapi: 3.1.0
info:
  title: Lora API
  version: 1.0.0
  description: Internal API for managing company short links
servers:
  - url: https://api.uselora.com
    description: Production
security:
  - bearerAuth: []
paths:
  /v1/shortcuts/{handle}:
    put:
      tags:
        - Shortcuts
      summary: Upsert shortcut
      description: >-
        Creates a shortcut at the given slug, or updates the existing one.
        Returns `201` when a new shortcut is created and `200` when an existing
        one is updated. The handle is taken verbatim as the slug — for symmetry
        with `GET`/`PATCH`/`DELETE` the segment is named `{handle}`, but PUT
        does not resolve UUID-shaped handles to a row's ID. One guardrail: a
        UUID-shaped handle that collides with an existing shortcut's `id`
        returns `400 validation_error` (use `PATCH /v1/shortcuts/{handle}` to
        update by ID); UUID-shaped slugs that don't collide are accepted as
        slugs.
      operationId: upsertShortcut
      parameters:
        - name: handle
          in: path
          required: true
          schema:
            type: string
          description: The shortcut's slug.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                destination:
                  type: string
                  maxLength: 32000
                  description: The destination URL of the short link.
                  examples:
                    - https://google.com
                    - mailto:hello@example.com
                    - tel:+1234567890
                    - notion://workspace/page
                title:
                  description: Optional title for the shortcut
                  type:
                    - string
                    - 'null'
                description:
                  description: Optional description for the shortcut
                  type:
                    - string
                    - 'null'
                visibility:
                  description: >-
                    Visibility level. Omit to keep the current value when
                    updating an existing shortcut, or to default to `WORKSPACE`
                    when creating a new one.
                  type: string
                  enum:
                    - PRIVATE
                    - WORKSPACE
                    - UNLISTED
                masked:
                  description: Whether to mask the destination URL
                  default: false
                  type: boolean
                password:
                  description: >-
                    The password required to access the destination URL of the
                    shortcut.
                  format: password
                  writeOnly: true
                  anyOf:
                    - type: string
                      minLength: 1
                      maxLength: 256
                    - type: string
                      const: ''
                    - type: 'null'
                expiresAt:
                  description: The date and time when the short link will expire at.
                  format: date-time
                  type:
                    - string
                    - 'null'
                ios:
                  description: >-
                    The iOS destination URL for the shortcut for iOS device
                    targeting.
                  anyOf:
                    - type: string
                      maxLength: 32000
                    - type: string
                      const: ''
                    - type: 'null'
                android:
                  description: >-
                    The Android destination URL for the shortcut for Android
                    device targeting.
                  anyOf:
                    - type: string
                      maxLength: 32000
                    - type: string
                      const: ''
                    - type: 'null'
                geo:
                  anyOf:
                    - $ref: '#/components/schemas/Geo'
                    - type: 'null'
                  description: >-
                    Geo targeting information for the short link in JSON format
                    {[COUNTRY]: https://example.com }
                folderId:
                  description: >-
                    The 8-character ID of an existing folder to assign the
                    shortcut to. Defaults to the workspace's default folder when
                    omitted.
                  examples:
                    - a1b2c3d4
                  type: string
                  pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
              required:
                - destination
              additionalProperties: false
              title: UpsertShortcutRequest
              description: >-
                The desired state of the shortcut at this slug. `tagIds` and
                similar associations aren't accepted here — use `POST
                /v1/shortcuts` or `PATCH /v1/shortcuts/{handle}` for those.
      responses:
        '200':
          description: The existing shortcut at this slug was updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                    description: The shortcut's unique ID.
                  slug:
                    type: string
                    description: The shortcut slug.
                  url:
                    type: string
                    description: >-
                      Workspace-scoped short link. Open this URL to record a
                      click and redirect to the destination.
                    examples:
                      - https://app.uselora.com/acme/short/handbook
                  destination:
                    type: string
                    description: The destination URL of the short link.
                  title:
                    type:
                      - string
                      - 'null'
                  description:
                    type:
                      - string
                      - 'null'
                  icon:
                    type:
                      - string
                      - 'null'
                  image:
                    type:
                      - string
                      - 'null'
                  video:
                    type:
                      - string
                      - 'null'
                  visibility:
                    type: string
                    enum:
                      - PRIVATE
                      - WORKSPACE
                      - UNLISTED
                      - PUBLIC
                  archived:
                    type: boolean
                    description: >-
                      Whether the short link is archived. Defaults to false if
                      not provided.
                  masked:
                    type: boolean
                  passwordProtected:
                    type: boolean
                    description: >-
                      Whether this shortcut requires a password before
                      redirecting. The password hash is never returned.
                  expiresAt:
                    type:
                      - string
                      - 'null'
                    description: The date and time when the short link will expire at.
                  ios:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The iOS destination URL for the shortcut for iOS device
                      targeting.
                  android:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The Android destination URL for the shortcut for Android
                      device targeting.
                  geo:
                    anyOf:
                      - $ref: '#/components/schemas/Geo'
                      - type: 'null'
                    description: >-
                      Geo targeting information for the short link in JSON
                      format {[COUNTRY]: https://example.com }
                  placeholders:
                    type: array
                    items:
                      $ref: '#/components/schemas/PlaceholderDescriptor'
                    description: >-
                      Dynamic placeholders parsed from the destination URL.
                      Empty for static destinations. See
                      docs/dynamic-placeholders.md.
                  folderId:
                    type: string
                    pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
                    description: The 8-character ID of the folder this shortcut belongs to.
                    examples:
                      - a1b2c3d4
                  tagIds:
                    default: []
                    description: The unique IDs of the tags assigned to the shortcut.
                    examples:
                      - - a1b2c3d4
                    type: array
                    items:
                      type: string
                      pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
                  externalId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The ID of the link in your database. If set, it can be
                      used to identify the link in future API requests (the
                      `ext_` prefix is recommended on query parameters for
                      visual disambiguation but the server accepts both prefixed
                      and bare values). This key is unique across your
                      workspace.
                  tenantId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The ID of the tenant that created the link inside your
                      system. If set, it can be used to fetch all links for a
                      tenant.
                  comments:
                    type:
                      - string
                      - 'null'
                    description: The comments for the short link.
                  workspaceId:
                    type: string
                    description: ID of the workspace the shortcut belongs to.
                  userId:
                    type: string
                    description: ID of the user who created the shortcut.
                  createdAt:
                    type: string
                    description: ISO 8601 creation timestamp.
                  updatedAt:
                    type: string
                    description: ISO 8601 timestamp of the last update.
                required:
                  - android
                  - archived
                  - comments
                  - createdAt
                  - description
                  - destination
                  - expiresAt
                  - externalId
                  - folderId
                  - geo
                  - icon
                  - id
                  - image
                  - ios
                  - masked
                  - slug
                  - tenantId
                  - title
                  - updatedAt
                  - userId
                  - video
                  - visibility
                  - workspaceId
                  - passwordProtected
                  - url
                  - placeholders
                  - tagIds
                additionalProperties: false
                title: Shortcut
                description: A shortcut.
        '201':
          description: A new shortcut was created at this slug.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                    description: The shortcut's unique ID.
                  slug:
                    type: string
                    description: The shortcut slug.
                  url:
                    type: string
                    description: >-
                      Workspace-scoped short link. Open this URL to record a
                      click and redirect to the destination.
                    examples:
                      - https://app.uselora.com/acme/short/handbook
                  destination:
                    type: string
                    description: The destination URL of the short link.
                  title:
                    type:
                      - string
                      - 'null'
                  description:
                    type:
                      - string
                      - 'null'
                  icon:
                    type:
                      - string
                      - 'null'
                  image:
                    type:
                      - string
                      - 'null'
                  video:
                    type:
                      - string
                      - 'null'
                  visibility:
                    type: string
                    enum:
                      - PRIVATE
                      - WORKSPACE
                      - UNLISTED
                      - PUBLIC
                  archived:
                    type: boolean
                    description: >-
                      Whether the short link is archived. Defaults to false if
                      not provided.
                  masked:
                    type: boolean
                  passwordProtected:
                    type: boolean
                    description: >-
                      Whether this shortcut requires a password before
                      redirecting. The password hash is never returned.
                  expiresAt:
                    type:
                      - string
                      - 'null'
                    description: The date and time when the short link will expire at.
                  ios:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The iOS destination URL for the shortcut for iOS device
                      targeting.
                  android:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The Android destination URL for the shortcut for Android
                      device targeting.
                  geo:
                    anyOf:
                      - $ref: '#/components/schemas/Geo'
                      - type: 'null'
                    description: >-
                      Geo targeting information for the short link in JSON
                      format {[COUNTRY]: https://example.com }
                  placeholders:
                    type: array
                    items:
                      $ref: '#/components/schemas/PlaceholderDescriptor'
                    description: >-
                      Dynamic placeholders parsed from the destination URL.
                      Empty for static destinations. See
                      docs/dynamic-placeholders.md.
                  folderId:
                    type: string
                    pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
                    description: The 8-character ID of the folder this shortcut belongs to.
                    examples:
                      - a1b2c3d4
                  tagIds:
                    default: []
                    description: The unique IDs of the tags assigned to the shortcut.
                    examples:
                      - - a1b2c3d4
                    type: array
                    items:
                      type: string
                      pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
                  externalId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The ID of the link in your database. If set, it can be
                      used to identify the link in future API requests (the
                      `ext_` prefix is recommended on query parameters for
                      visual disambiguation but the server accepts both prefixed
                      and bare values). This key is unique across your
                      workspace.
                  tenantId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The ID of the tenant that created the link inside your
                      system. If set, it can be used to fetch all links for a
                      tenant.
                  comments:
                    type:
                      - string
                      - 'null'
                    description: The comments for the short link.
                  workspaceId:
                    type: string
                    description: ID of the workspace the shortcut belongs to.
                  userId:
                    type: string
                    description: ID of the user who created the shortcut.
                  createdAt:
                    type: string
                    description: ISO 8601 creation timestamp.
                  updatedAt:
                    type: string
                    description: ISO 8601 timestamp of the last update.
                required:
                  - android
                  - archived
                  - comments
                  - createdAt
                  - description
                  - destination
                  - expiresAt
                  - externalId
                  - folderId
                  - geo
                  - icon
                  - id
                  - image
                  - ios
                  - masked
                  - slug
                  - tenantId
                  - title
                  - updatedAt
                  - userId
                  - video
                  - visibility
                  - workspaceId
                  - passwordProtected
                  - url
                  - placeholders
                  - tagIds
                additionalProperties: false
                title: Shortcut
                description: A shortcut.
        '400':
          description: >-
            The request body failed validation, wasn't valid JSON, the slug is
            reserved, `expiresAt` is in the past on a create (the update branch
            accepts past values), or the `{handle}` is a UUID that matches an
            existing shortcut's `id` (use `PATCH /v1/shortcuts/{handle}` to
            update by ID).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  fieldErrors:
                    type: object
                    propertyNames:
                      type: string
                    additionalProperties:
                      type: array
                      items:
                        type: string
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - requestId
                additionalProperties: false
          headers:
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
        '401':
          description: Missing, malformed, unknown, or workspace-unscoped Bearer token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - requestId
                additionalProperties: false
          headers:
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
        '403':
          description: >-
            The caller is authenticated but not allowed to perform this action.
            Common codes: `insufficient_scope` (the key lacks the required
            scope; body sets `required_scope`) and `no_permission` (the caller
            is no longer a workspace member).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                  required_scope:
                    description: >-
                      Set when `code` is `insufficient_scope`. The exact scope
                      name the route required, e.g. `shortcuts.write`.
                    type: string
                required:
                  - error
                  - requestId
                additionalProperties: false
          headers:
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
        '404':
          description: >-
            The supplied `folderId` doesn't exist in this workspace
            (`folder_not_found`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - requestId
                additionalProperties: false
          headers:
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
        '409':
          description: >-
            A shortcut at this slug exists but isn't visible to the caller (for
            example another user's private shortcut). Pick a different slug.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - requestId
                additionalProperties: false
          headers:
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
        '429':
          description: Rate limit exceeded. Wait `Retry-After` seconds before retrying.
          headers:
            Retry-After:
              schema:
                type: integer
                minimum: 1
              description: Seconds until the rate-limit window resets.
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - requestId
                additionalProperties: false
        '500':
          description: >-
            An unexpected failure on the server. The body is `{ error:
            <message>, code: "internal_error", requestId: <id> }`, plus
            `traceId` when available. Idempotent operations (GET, DELETE) and
            writes that carry an `Idempotency-Key` header are safe to retry with
            exponential backoff. Other writes may have partially applied;
            surface the error to the caller instead of retrying blindly.
          headers:
            X-Lora-Request-Id:
              description: >-
                Request correlation identifier. Matches the `requestId` field in
                the JSON error body.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                    const: internal_error
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Sentry trace ID when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - code
                  - requestId
                additionalProperties: false
components:
  schemas:
    Geo:
      type: object
      propertyNames:
        type: string
        pattern: ^[A-Za-z]{2}$
      additionalProperties:
        type: string
        maxLength: 32000
      title: Geo
      description: >-
        Country-specific destination overrides keyed by ISO-3166-1 alpha-2
        country code.
    PlaceholderDescriptor:
      type: object
      properties:
        name:
          type: string
          description: Placeholder name (between curly braces).
        default:
          description: Default value substituted when no value is captured at click time.
          type:
            - string
            - 'null'
      required:
        - name
        - default
      additionalProperties: false
      title: PlaceholderDescriptor
      description: A dynamic placeholder declared in a shortcut's destination URL.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````