> ## 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: >-
    Lora REST API for managing workspace shortcuts, folders, tags, and QR codes.


    ## Versioning

    All stable endpoints are prefixed with `/v1/`. Breaking changes ship under a
    new path prefix (for example `/v2/`).

    Non-breaking additions (new optional fields, new endpoints) may land in the
    current version.

    Deprecated endpoints are announced in the [developer
    docs](https://uselora.dev) before removal.


    ## Authentication

    Send `Authorization: Bearer <api_key>` on every request except `GET /v1/qr`,
    which also accepts anonymous callers. API keys are workspace-scoped and
    carry OAuth-style scopes (for example `shortcuts.write`).


    ## Errors

    4xx and 5xx responses use a typed JSON envelope: `{ error, code?, requestId,
    traceId?, fieldErrors?, required_scope?, current_plan?, required_capability?
    }`.

    See components `ErrorResponse`, `ErrorWithFieldErrors`,
    `PaymentRequiredError`, `ForbiddenError`, and `InternalError`.


    ## Rate limits

    Successful responses include `RateLimit-Limit`, `RateLimit-Remaining`, and
    `RateLimit-Reset` (IETF RateLimit fields).

    429 responses include `Retry-After` (seconds). Authenticated callers are
    bucketed per API key; anonymous QR endpoints are bucketed per IP.


    ## Discovery

    - OpenAPI spec: `GET https://api.uselora.com/openapi.json` (also `GET
    https://api.uselora.com/`)

    - RFC 9727 catalog: `GET https://www.uselora.com/.well-known/api-catalog`

    - MCP manifest: `GET https://www.uselora.com/.well-known/mcp` (server card
    at `/.well-known/mcp/server-card.json`)

    - MCP Streamable HTTP endpoint: `POST https://api.uselora.com/mcp`
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
                  minLength: 1
                  maxLength: 32000
                  description: The shortcut's destination URL.
                  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 shortcut expires.
                  format: date-time
                  type:
                    - string
                    - 'null'
                dynamicRouting:
                  anyOf:
                    - $ref: '#/components/schemas/DynamicRouting'
                    - type: 'null'
                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`,
                `aliases`, 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 shortcut URL. Open it to record a click
                      and redirect to the destination.
                    examples:
                      - https://app.uselora.com/acme/short/handbook
                  destination:
                    type: string
                    description: The shortcut's destination URL.
                  title:
                    type:
                      - string
                      - 'null'
                  description:
                    type:
                      - string
                      - 'null'
                  icon:
                    type:
                      - string
                      - 'null'
                  iconSettings:
                    description: >-
                      Structured icon recipe (glyph + background). `null` when
                      the default monogram-on-neutral design is used.
                    type:
                      - object
                      - 'null'
                    properties:
                      background:
                        type: object
                        properties:
                          color:
                            type:
                              - string
                              - 'null'
                            pattern: ^#[0-9A-F]{6}$
                          type:
                            type: string
                            enum:
                              - color
                              - neutral
                        required:
                          - color
                          - type
                        additionalProperties: false
                      glyph:
                        type: object
                        properties:
                          ref:
                            type:
                              - string
                              - 'null'
                          source:
                            type: string
                            enum:
                              - favicon
                              - monogram
                              - upload
                          variant:
                            type: string
                            enum:
                              - color
                              - mono
                        required:
                          - ref
                          - source
                          - variant
                        additionalProperties: false
                    required:
                      - background
                      - glyph
                    additionalProperties: false
                  image:
                    type:
                      - string
                      - 'null'
                  video:
                    type:
                      - string
                      - 'null'
                  visibility:
                    type: string
                    enum:
                      - PRIVATE
                      - WORKSPACE
                      - UNLISTED
                  archived:
                    type: boolean
                    description: >-
                      Whether the shortcut 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 shortcut expires.
                  dynamicRouting:
                    anyOf:
                      - $ref: '#/components/schemas/DynamicRouting'
                      - type: 'null'
                    description: >-
                      Ordered routing rules, evaluated top to bottom — the first
                      rule whose conditions all match wins. Conditions within a
                      rule are ANDed; values within a condition are ORed.
                      Visitors matching no rule get the shortcut's default
                      `destination`.
                  placeholders:
                    type: array
                    items:
                      $ref: '#/components/schemas/PlaceholderDescriptor'
                    description: >-
                      Dynamic placeholders parsed from the destination URL, in
                      template order (e.g. `{query}`). Empty for static
                      destinations.
                  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}$
                  aliases:
                    default: []
                    description: >-
                      Additional handles that resolve to this shortcut in the
                      same namespace as the canonical slug.
                    examples:
                      - - urlaub
                        - ferien
                    type: array
                    items:
                      type: string
                      minLength: 1
                      maxLength: 50
                      pattern: ^[a-z0-9]([a-z0-9-_]*[a-z0-9])?$
                  externalId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The shortcut ID in your system. If set, it can identify
                      the shortcut in future API requests. The `ext_` prefix is
                      recommended on query parameters for visual disambiguation,
                      but the server accepts prefixed and bare values. This key
                      is unique across your workspace.
                  tenantId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The ID of the tenant that created the shortcut in your
                      system. If set, it can be used to fetch all shortcuts for
                      a tenant.
                  comments:
                    type:
                      - string
                      - 'null'
                    description: Comments about the shortcut.
                  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.
                  metadataSync:
                    type: object
                    properties:
                      description:
                        type: string
                        enum:
                          - auto
                          - manual
                      title:
                        type: string
                        enum:
                          - auto
                          - manual
                    required:
                      - description
                      - title
                    additionalProperties: false
                    description: >-
                      Whether `title` and `description` are still kept in sync
                      with the destination automatically, or have been
                      overridden by hand. The screenshot's own sync state is
                      `previewSettings.source`.
                  previewSettings:
                    description: >-
                      Stored destination screenshot for the hover preview.
                      `null` when none has been resolved yet; `source: "none"`
                      when the owner declined one. Use the resolved `previewUrl`
                      / `previewDarkUrl` to render it — `assetId` and `blobHost`
                      describe where it is stored and are not accepted on a
                      write.
                    type:
                      - object
                      - 'null'
                    properties:
                      assetId:
                        type:
                          - string
                          - 'null'
                        pattern: >-
                          ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
                      blobHost:
                        type:
                          - string
                          - 'null'
                        maxLength: 253
                        pattern: >-
                          ^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+(?::\d{1,5})?$
                      capturedAt:
                        type:
                          - string
                          - 'null'
                        format: date-time
                        pattern: >-
                          ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
                      capturedFor:
                        type:
                          - string
                          - 'null'
                        maxLength: 32000
                      hasDark:
                        type: boolean
                      height:
                        type:
                          - integer
                          - 'null'
                        exclusiveMinimum: 0
                        maximum: 2560
                      source:
                        type: string
                        enum:
                          - screenshot
                          - opengraph
                          - upload
                          - none
                      width:
                        type:
                          - integer
                          - 'null'
                        exclusiveMinimum: 0
                        maximum: 2560
                    required:
                      - assetId
                      - blobHost
                      - capturedAt
                      - capturedFor
                      - hasDark
                      - height
                      - source
                      - width
                    additionalProperties: false
                  qrSettings:
                    description: >-
                      Saved QR code design for this shortcut. `null` when the
                      default design is used. Customization requires a paid
                      plan.
                    type:
                      - object
                      - 'null'
                    properties:
                      dotColor:
                        type: string
                        pattern: ^#[0-9A-Fa-f]{6}$
                      dotStyle:
                        type: string
                        enum:
                          - square
                          - dots
                          - rounded
                      frame:
                        type: string
                        enum:
                          - none
                          - solid-logo
                          - solid-scan
                          - solid-slug
                          - window-logo
                          - window-scan
                          - window-slug
                          - card-logo
                          - card-scan
                          - card-slug
                      hideLogo:
                        type: boolean
                      markerBorder:
                        type: string
                        enum:
                          - square
                          - rounded
                          - circle
                      markerCenter:
                        type: string
                        enum:
                          - square
                          - dot
                      markerColor:
                        type: string
                        pattern: ^#[0-9A-Fa-f]{6}$
                    additionalProperties: false
                  previewUrl:
                    description: >-
                      Resolved URL of the light screenshot, or `null` when there
                      is none.
                    type:
                      - string
                      - 'null'
                  previewDarkUrl:
                    description: >-
                      Resolved URL of the dark screenshot, or `null` when the
                      preview has no dark variant.
                    type:
                      - string
                      - 'null'
                  additionalFolderIds:
                    default: []
                    description: >-
                      Short IDs of ADDITIONAL folders this shortcut appears in,
                      excluding its primary folder (`folderId`). Empty array
                      when it only lives in its primary folder. Settable at
                      create; curate afterwards via the folder items endpoints.
                      Folders you cannot see are omitted.
                    examples:
                      - - a1b2c3d4
                    type: array
                    items:
                      type: string
                      pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
                required:
                  - archived
                  - comments
                  - createdAt
                  - description
                  - destination
                  - dynamicRouting
                  - expiresAt
                  - externalId
                  - folderId
                  - icon
                  - id
                  - image
                  - masked
                  - metadataSync
                  - slug
                  - tenantId
                  - title
                  - updatedAt
                  - userId
                  - video
                  - visibility
                  - workspaceId
                  - passwordProtected
                  - previewUrl
                  - previewDarkUrl
                  - url
                  - placeholders
                  - tagIds
                  - additionalFolderIds
                  - aliases
                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 shortcut URL. Open it to record a click
                      and redirect to the destination.
                    examples:
                      - https://app.uselora.com/acme/short/handbook
                  destination:
                    type: string
                    description: The shortcut's destination URL.
                  title:
                    type:
                      - string
                      - 'null'
                  description:
                    type:
                      - string
                      - 'null'
                  icon:
                    type:
                      - string
                      - 'null'
                  iconSettings:
                    description: >-
                      Structured icon recipe (glyph + background). `null` when
                      the default monogram-on-neutral design is used.
                    type:
                      - object
                      - 'null'
                    properties:
                      background:
                        type: object
                        properties:
                          color:
                            type:
                              - string
                              - 'null'
                            pattern: ^#[0-9A-F]{6}$
                          type:
                            type: string
                            enum:
                              - color
                              - neutral
                        required:
                          - color
                          - type
                        additionalProperties: false
                      glyph:
                        type: object
                        properties:
                          ref:
                            type:
                              - string
                              - 'null'
                          source:
                            type: string
                            enum:
                              - favicon
                              - monogram
                              - upload
                          variant:
                            type: string
                            enum:
                              - color
                              - mono
                        required:
                          - ref
                          - source
                          - variant
                        additionalProperties: false
                    required:
                      - background
                      - glyph
                    additionalProperties: false
                  image:
                    type:
                      - string
                      - 'null'
                  video:
                    type:
                      - string
                      - 'null'
                  visibility:
                    type: string
                    enum:
                      - PRIVATE
                      - WORKSPACE
                      - UNLISTED
                  archived:
                    type: boolean
                    description: >-
                      Whether the shortcut 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 shortcut expires.
                  dynamicRouting:
                    anyOf:
                      - $ref: '#/components/schemas/DynamicRouting'
                      - type: 'null'
                    description: >-
                      Ordered routing rules, evaluated top to bottom — the first
                      rule whose conditions all match wins. Conditions within a
                      rule are ANDed; values within a condition are ORed.
                      Visitors matching no rule get the shortcut's default
                      `destination`.
                  placeholders:
                    type: array
                    items:
                      $ref: '#/components/schemas/PlaceholderDescriptor'
                    description: >-
                      Dynamic placeholders parsed from the destination URL, in
                      template order (e.g. `{query}`). Empty for static
                      destinations.
                  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}$
                  aliases:
                    default: []
                    description: >-
                      Additional handles that resolve to this shortcut in the
                      same namespace as the canonical slug.
                    examples:
                      - - urlaub
                        - ferien
                    type: array
                    items:
                      type: string
                      minLength: 1
                      maxLength: 50
                      pattern: ^[a-z0-9]([a-z0-9-_]*[a-z0-9])?$
                  externalId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The shortcut ID in your system. If set, it can identify
                      the shortcut in future API requests. The `ext_` prefix is
                      recommended on query parameters for visual disambiguation,
                      but the server accepts prefixed and bare values. This key
                      is unique across your workspace.
                  tenantId:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The ID of the tenant that created the shortcut in your
                      system. If set, it can be used to fetch all shortcuts for
                      a tenant.
                  comments:
                    type:
                      - string
                      - 'null'
                    description: Comments about the shortcut.
                  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.
                  metadataSync:
                    type: object
                    properties:
                      description:
                        type: string
                        enum:
                          - auto
                          - manual
                      title:
                        type: string
                        enum:
                          - auto
                          - manual
                    required:
                      - description
                      - title
                    additionalProperties: false
                    description: >-
                      Whether `title` and `description` are still kept in sync
                      with the destination automatically, or have been
                      overridden by hand. The screenshot's own sync state is
                      `previewSettings.source`.
                  previewSettings:
                    description: >-
                      Stored destination screenshot for the hover preview.
                      `null` when none has been resolved yet; `source: "none"`
                      when the owner declined one. Use the resolved `previewUrl`
                      / `previewDarkUrl` to render it — `assetId` and `blobHost`
                      describe where it is stored and are not accepted on a
                      write.
                    type:
                      - object
                      - 'null'
                    properties:
                      assetId:
                        type:
                          - string
                          - 'null'
                        pattern: >-
                          ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
                      blobHost:
                        type:
                          - string
                          - 'null'
                        maxLength: 253
                        pattern: >-
                          ^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+(?::\d{1,5})?$
                      capturedAt:
                        type:
                          - string
                          - 'null'
                        format: date-time
                        pattern: >-
                          ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
                      capturedFor:
                        type:
                          - string
                          - 'null'
                        maxLength: 32000
                      hasDark:
                        type: boolean
                      height:
                        type:
                          - integer
                          - 'null'
                        exclusiveMinimum: 0
                        maximum: 2560
                      source:
                        type: string
                        enum:
                          - screenshot
                          - opengraph
                          - upload
                          - none
                      width:
                        type:
                          - integer
                          - 'null'
                        exclusiveMinimum: 0
                        maximum: 2560
                    required:
                      - assetId
                      - blobHost
                      - capturedAt
                      - capturedFor
                      - hasDark
                      - height
                      - source
                      - width
                    additionalProperties: false
                  qrSettings:
                    description: >-
                      Saved QR code design for this shortcut. `null` when the
                      default design is used. Customization requires a paid
                      plan.
                    type:
                      - object
                      - 'null'
                    properties:
                      dotColor:
                        type: string
                        pattern: ^#[0-9A-Fa-f]{6}$
                      dotStyle:
                        type: string
                        enum:
                          - square
                          - dots
                          - rounded
                      frame:
                        type: string
                        enum:
                          - none
                          - solid-logo
                          - solid-scan
                          - solid-slug
                          - window-logo
                          - window-scan
                          - window-slug
                          - card-logo
                          - card-scan
                          - card-slug
                      hideLogo:
                        type: boolean
                      markerBorder:
                        type: string
                        enum:
                          - square
                          - rounded
                          - circle
                      markerCenter:
                        type: string
                        enum:
                          - square
                          - dot
                      markerColor:
                        type: string
                        pattern: ^#[0-9A-Fa-f]{6}$
                    additionalProperties: false
                  previewUrl:
                    description: >-
                      Resolved URL of the light screenshot, or `null` when there
                      is none.
                    type:
                      - string
                      - 'null'
                  previewDarkUrl:
                    description: >-
                      Resolved URL of the dark screenshot, or `null` when the
                      preview has no dark variant.
                    type:
                      - string
                      - 'null'
                  additionalFolderIds:
                    default: []
                    description: >-
                      Short IDs of ADDITIONAL folders this shortcut appears in,
                      excluding its primary folder (`folderId`). Empty array
                      when it only lives in its primary folder. Settable at
                      create; curate afterwards via the folder items endpoints.
                      Folders you cannot see are omitted.
                    examples:
                      - - a1b2c3d4
                    type: array
                    items:
                      type: string
                      pattern: ^[0-9abcdefghjkmnpqrstvwxyz]{8}$
                required:
                  - archived
                  - comments
                  - createdAt
                  - description
                  - destination
                  - dynamicRouting
                  - expiresAt
                  - externalId
                  - folderId
                  - icon
                  - id
                  - image
                  - masked
                  - metadataSync
                  - slug
                  - tenantId
                  - title
                  - updatedAt
                  - userId
                  - video
                  - visibility
                  - workspaceId
                  - passwordProtected
                  - previewUrl
                  - previewDarkUrl
                  - url
                  - placeholders
                  - tagIds
                  - additionalFolderIds
                  - aliases
                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: >-
                      Trace identifier 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: >-
                      Trace identifier 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
        '402':
          description: >-
            The workspace plan does not include API access, the requested
            capability, or enough resource capacity. The body uses
            `plan_requires_upgrade` or `quota_exceeded`. Upgrade the workspace
            or change the request; retrying the same request will not succeed.
          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
                    enum:
                      - plan_requires_upgrade
                      - quota_exceeded
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Trace identifier when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                  current_plan:
                    description: The workspace plan when the response includes it.
                    type: string
                  required_capability:
                    description: >-
                      The required plan capability when the response includes
                      it.
                    type: string
                required:
                  - error
                  - code
                  - requestId
                additionalProperties: false
        '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: >-
                      Trace identifier 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: >-
                      Trace identifier 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: >-
                      Trace identifier 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
        '413':
          description: >-
            The request body exceeded the size limit. The body is rejected
            before being parsed, so no partial write occurred; retrying with a
            smaller payload will succeed.
          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: payload_too_large
                  requestId:
                    type: string
                    description: >-
                      Correlation identifier for support/debugging. Equals the
                      `X-Lora-Request-Id` response header.
                  traceId:
                    description: >-
                      Trace identifier when available for this request.
                      32-character lowercase hex string.
                    type: string
                    pattern: ^[0-9a-f]{32}$
                required:
                  - error
                  - code
                  - requestId
                additionalProperties: false
        '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: >-
                      Trace identifier 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. Retry idempotent operations with
            exponential backoff. A write may already have applied; reconcile its
            state before retrying.
          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: >-
                      Trace identifier 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:
    DynamicRouting:
      maxItems: 10
      type: array
      items:
        $ref: '#/components/schemas/DynamicRoutingRule'
      title: DynamicRouting
      description: >-
        Ordered routing rules, evaluated top to bottom — the first rule whose
        conditions all match wins. Conditions within a rule are ANDed; values
        within a condition are ORed. Visitors matching no rule get the
        shortcut's default `destination`. At most 10 rules. Pass `[]` or `null`
        to remove all rules.
    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'
        label:
          default: null
          description: >-
            Human-facing label shown on the prompt fields a visitor fills in.
            Null when omitted, in which case clients fall back to `name`. Never
            used as a query key.
          type:
            - string
            - 'null'
      required:
        - name
        - default
        - label
      additionalProperties: false
      title: PlaceholderDescriptor
      description: A dynamic placeholder declared in a shortcut's destination URL.
    DynamicRoutingRule:
      type: object
      properties:
        conditions:
          minItems: 1
          maxItems: 2
          type: array
          items:
            $ref: '#/components/schemas/DynamicRoutingCondition'
          description: >-
            Conditions to satisfy, ANDed together. At most 2 — one per
            attribute.
        destination:
          type: string
          minLength: 1
          maxLength: 32000
          description: >-
            Where to send visitors matching this rule. Same scheme rules as the
            shortcut's default `destination`, and dynamic placeholders work here
            too.
          examples:
            - https://apps.apple.com/de/app/id123456789
      required:
        - conditions
        - destination
      additionalProperties: false
      title: DynamicRoutingRule
      description: A set of ANDed conditions and the destination they select.
    DynamicRoutingCondition:
      oneOf:
        - type: object
          properties:
            attribute:
              type: string
              const: country
            operator:
              type: string
              enum:
                - is
                - is_not
              description: >-
                `is` matches when the visitor attribute is one of `values`;
                `is_not` matches when it is not. A visitor attribute we cannot
                determine (no geo signal, or a non-phone / unclassifiable user
                agent) never satisfies `is` and always satisfies `is_not`.
            values:
              minItems: 1
              maxItems: 250
              type: array
              items:
                type: string
                pattern: ^[A-Za-z]{2}$
              description: >-
                ISO-3166-1 alpha-2 country codes. Matched case-insensitively and
                stored uppercase.
              examples:
                - - DE
                  - AT
                  - CH
          required:
            - attribute
            - operator
            - values
          additionalProperties: false
        - type: object
          properties:
            attribute:
              type: string
              const: platform
            operator:
              type: string
              enum:
                - is
                - is_not
              description: >-
                `is` matches when the visitor attribute is one of `values`;
                `is_not` matches when it is not. A visitor attribute we cannot
                determine (no geo signal, or a non-phone / unclassifiable user
                agent) never satisfies `is` and always satisfies `is_not`.
            values:
              minItems: 1
              maxItems: 2
              type: array
              items:
                type: string
                enum:
                  - ios
                  - android
              description: >-
                Phone platforms. Tablets, desktops and unclassifiable clients
                are not any of these — they fall through to `destination` unless
                an `is_not` condition catches them.
              examples:
                - - ios
          required:
            - attribute
            - operator
            - values
          additionalProperties: false
      title: DynamicRoutingCondition
      description: >-
        One test against a visitor attribute. Values inside a condition are
        ORed.
      type: object
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````