openapi: 3.0.3
info:
  title: 'ShortURL.FM API Documentation'
  description: "Authenticated API for creating, managing, and inspecting short URLs on ShortURL.FM.\n\nThis documentation covers the authenticated <code>v1</code> API for ShortURL.FM.\nAll endpoints require a Sanctum personal access token sent as a Bearer token."
  version: 1.0.0
servers:
  -
    url: 'https://shorturl.fm'
tags:
  -
    name: Domains
    description: "\nLook up short-link domains that can be used when creating URLs."
  -
    name: 'Short URLs'
    description: "\nCreate, inspect, update, and analyze the authenticated user's short URLs."
  -
    name: Tokens
    description: "\nManage Sanctum personal access tokens for API clients."
  -
    name: Utilities
    description: "\nResolve existing short URLs."
  -
    name: Endpoints
    description: ''
components:
  securitySchemes:
    default:
      type: http
      scheme: bearer
      description: 'Create a Sanctum token from the <b>API tokens</b> section in your profile.'
security:
  -
    default: []
paths:
  /api/v1/domains:
    get:
      summary: 'List active domains.'
      operationId: listActiveDomains
      description: "Returns the domains currently available for short URL creation, with the default domain first.\nRate limit: `200/hour`, `4,800/day`, `30,000/month`."
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 1
                      host: shorturl.fm
                      is_default: true
                    -
                      id: 2
                      host: shorturl.sh
                      is_default: false
                  error: null
                  meta:
                    trace_id: bcde4e74-26d5-4261-8c86-c1cb270d3af0
                    timestamp: '2026-03-06T12:03:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    example:
                      -
                        id: 1
                        host: shorturl.fm
                        is_default: true
                      -
                        id: 2
                        host: shorturl.sh
                        is_default: false
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        host:
                          type: string
                          example: shorturl.fm
                        is_default:
                          type: boolean
                          example: true
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: bcde4e74-26d5-4261-8c86-c1cb270d3af0
                      timestamp:
                        type: string
                        example: '2026-03-06T12:03:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - Domains
  /api/v1/short-urls:
    post:
      summary: 'Create a short URL.'
      operationId: createAShortURL
      description: "Creates a new short URL for the authenticated user. If `alias` is omitted, the server generates a random code.\nBase rate limit: `200/hour`, `4,800/day`, `30,000/month`.\nAdditional limits apply when `log_stats=true` and/or `qr_enabled=true`: `100/hour`, `2,400/day`, `10,000/month`."
      parameters: []
      responses:
        201:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    id: 42
                    short_url: 'https://shorturl.fm/Docs-42'
                    long_url: 'https://example.com/very/long/path'
                    domain: shorturl.fm
                    short_code: Docs-42
                    total_clicks: 131
                    log_stats: true
                    expires_at: '2026-12-31 23:59:59'
                    has_password: true
                    qr_enabled: true
                    qr_svg_download_url: 'https://shorturl.fm/short-urls/42/qr/svg'
                    qr_png_download_url: 'https://shorturl.fm/short-urls/42/qr/png'
                    qr_webp_download_url: 'https://shorturl.fm/short-urls/42/qr/webp'
                    created_at: '2026-03-01 09:30:00'
                    updated_at: '2026-03-06 11:45:00'
                    stats_url: 'https://shorturl.fm/Docs-42+'
                  error: null
                  meta:
                    trace_id: 2bdb40b1-49fd-4abf-8b7b-26db74bc2825
                    timestamp: '2026-03-06T12:04:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 42
                      short_url:
                        type: string
                        example: 'https://shorturl.fm/Docs-42'
                      long_url:
                        type: string
                        example: 'https://example.com/very/long/path'
                      domain:
                        type: string
                        example: shorturl.fm
                      short_code:
                        type: string
                        example: Docs-42
                      total_clicks:
                        type: integer
                        example: 131
                      log_stats:
                        type: boolean
                        example: true
                      expires_at:
                        type: string
                        example: '2026-12-31 23:59:59'
                      has_password:
                        type: boolean
                        example: true
                      qr_enabled:
                        type: boolean
                        example: true
                      qr_svg_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/svg'
                      qr_png_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/png'
                      qr_webp_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/webp'
                      created_at:
                        type: string
                        example: '2026-03-01 09:30:00'
                      updated_at:
                        type: string
                        example: '2026-03-06 11:45:00'
                      stats_url:
                        type: string
                        example: 'https://shorturl.fm/Docs-42+'
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bdb40b1-49fd-4abf-8b7b-26db74bc2825
                      timestamp:
                        type: string
                        example: '2026-03-06T12:04:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                oneOf:
                  -
                    description: 'URL is blacklisted'
                    type: object
                    example:
                      success: false
                      data: null
                      error:
                        message: 'This URL is blacklisted.'
                        details: {  }
                      meta:
                        trace_id: 7287efd5-3071-4829-9fda-b5ef4ed6cb90
                        timestamp: '2026-03-06T12:06:00+00:00'
                    properties:
                      success:
                        type: boolean
                        example: false
                      data:
                        type: string
                        example: null
                        nullable: true
                      error:
                        type: object
                        properties:
                          message:
                            type: string
                            example: 'This URL is blacklisted.'
                          details:
                            type: object
                            properties: {  }
                      meta:
                        type: object
                        properties:
                          trace_id:
                            type: string
                            example: 7287efd5-3071-4829-9fda-b5ef4ed6cb90
                          timestamp:
                            type: string
                            example: '2026-03-06T12:06:00+00:00'
                  -
                    description: 'Email verification required'
                    type: object
                    example:
                      success: false
                      data: null
                      error:
                        message: 'Please verify your email address before continuing.'
                        details:
                          status: email-verification-required
                          verify_email_url: /app/verify-email
                      meta:
                        trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                        timestamp: '2026-03-24T12:00:00+00:00'
                    properties:
                      success:
                        type: boolean
                        example: false
                      data:
                        type: string
                        example: null
                        nullable: true
                      error:
                        type: object
                        properties:
                          message:
                            type: string
                            example: 'Please verify your email address before continuing.'
                          details:
                            type: object
                            properties:
                              status:
                                type: string
                                example: email-verification-required
                              verify_email_url:
                                type: string
                                example: /app/verify-email
                      meta:
                        type: object
                        properties:
                          trace_id:
                            type: string
                            example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                          timestamp:
                            type: string
                            example: '2026-03-24T12:00:00+00:00'
        422:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'The given data was invalid.'
                    details:
                      validation:
                        url:
                          - 'The url field is required.'
                  meta:
                    trace_id: f4066217-792f-4f28-a243-e3a36f1b1e3e
                    timestamp: '2026-03-06T12:07:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'The given data was invalid.'
                      details:
                        type: object
                        properties:
                          validation:
                            type: object
                            properties:
                              url:
                                type: array
                                example:
                                  - 'The url field is required.'
                                items:
                                  type: string
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f4066217-792f-4f28-a243-e3a36f1b1e3e
                      timestamp:
                        type: string
                        example: '2026-03-06T12:07:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - 'Short URLs'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: 'The destination URL to shorten.'
                  example: 'https://example.com/very/long/path'
                domain_id:
                  type: integer
                  description: 'The active short domain to use. If omitted, the default domain is used.'
                  example: null
                alias:
                  type: string
                  description: 'Custom short code. Must be 5-30 characters using letters, digits, and hyphens.'
                  example: null
                log_stats:
                  type: boolean
                  description: 'Enable click tracking for this short URL.'
                  example: null
                qr_enabled:
                  type: boolean
                  description: 'Generate QR code downloads for the short URL.'
                  example: null
                expires_at:
                  type: string
                  description: 'Expiration timestamp in the future.'
                  example: null
                link_password:
                  type: string
                  description: 'Password that must be entered before redirecting.'
                  example: null
              required:
                - url
    get:
      summary: 'List short URLs.'
      operationId: listShortURLs
      description: "Returns the authenticated user's short URLs in reverse chronological order.\nRate limit: `200/hour`, `4,800/day`, `30,000/month`."
      parameters:
        -
          in: query
          name: page
          description: 'Page number for pagination.'
          example: 1
          required: false
          schema:
            type: integer
            description: 'Page number for pagination.'
            example: 1
        -
          in: query
          name: per_page
          description: 'Number of items per page. Must be between 1 and 100.'
          example: 20
          required: false
          schema:
            type: integer
            description: 'Number of items per page. Must be between 1 and 100.'
            example: 20
        -
          in: query
          name: search
          description: 'Filter results by matching part of the original URL or short code.'
          example: promo
          required: false
          schema:
            type: string
            description: 'Filter results by matching part of the original URL or short code.'
            example: promo
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    -
                      id: 42
                      short_url: 'https://shorturl.fm/Docs-42'
                      long_url: 'https://example.com/very/long/path'
                      domain: shorturl.fm
                      short_code: Docs-42
                      total_clicks: 131
                      log_stats: true
                      expires_at: '2026-12-31 23:59:59'
                      has_password: true
                      qr_enabled: true
                      qr_svg_download_url: 'https://shorturl.fm/short-urls/42/qr/svg'
                      qr_png_download_url: 'https://shorturl.fm/short-urls/42/qr/png'
                      qr_webp_download_url: 'https://shorturl.fm/short-urls/42/qr/webp'
                      created_at: '2026-03-01 09:30:00'
                      updated_at: '2026-03-06 11:45:00'
                      stats_url: 'https://shorturl.fm/Docs-42+'
                    -
                      id: 41
                      short_url: 'https://go.shorturl.fm/Sale-25'
                      long_url: 'https://example.com/spring-sale'
                      domain: go.shorturl.fm
                      short_code: Sale-25
                      total_clicks: 54
                      log_stats: true
                      expires_at: null
                      has_password: false
                      qr_enabled: false
                      qr_svg_download_url: null
                      qr_png_download_url: null
                      qr_webp_download_url: null
                      created_at: '2026-02-25 14:10:00'
                      updated_at: '2026-03-02 08:00:00'
                      stats_url: 'https://go.shorturl.fm/Sale-25+'
                  error: null
                  meta:
                    trace_id: f23696de-c811-41fd-b465-cf53539f7f4b
                    timestamp: '2026-03-06T12:05:00+00:00'
                    pagination:
                      current_page: 1
                      last_page: 3
                      per_page: 20
                      total: 42
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    example:
                      -
                        id: 42
                        short_url: 'https://shorturl.fm/Docs-42'
                        long_url: 'https://example.com/very/long/path'
                        domain: shorturl.fm
                        short_code: Docs-42
                        total_clicks: 131
                        log_stats: true
                        expires_at: '2026-12-31 23:59:59'
                        has_password: true
                        qr_enabled: true
                        qr_svg_download_url: 'https://shorturl.fm/short-urls/42/qr/svg'
                        qr_png_download_url: 'https://shorturl.fm/short-urls/42/qr/png'
                        qr_webp_download_url: 'https://shorturl.fm/short-urls/42/qr/webp'
                        created_at: '2026-03-01 09:30:00'
                        updated_at: '2026-03-06 11:45:00'
                        stats_url: 'https://shorturl.fm/Docs-42+'
                      -
                        id: 41
                        short_url: 'https://go.shorturl.fm/Sale-25'
                        long_url: 'https://example.com/spring-sale'
                        domain: go.shorturl.fm
                        short_code: Sale-25
                        total_clicks: 54
                        log_stats: true
                        expires_at: null
                        has_password: false
                        qr_enabled: false
                        qr_svg_download_url: null
                        qr_png_download_url: null
                        qr_webp_download_url: null
                        created_at: '2026-02-25 14:10:00'
                        updated_at: '2026-03-02 08:00:00'
                        stats_url: 'https://go.shorturl.fm/Sale-25+'
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 42
                        short_url:
                          type: string
                          example: 'https://shorturl.fm/Docs-42'
                        long_url:
                          type: string
                          example: 'https://example.com/very/long/path'
                        domain:
                          type: string
                          example: shorturl.fm
                        short_code:
                          type: string
                          example: Docs-42
                        total_clicks:
                          type: integer
                          example: 131
                        log_stats:
                          type: boolean
                          example: true
                        expires_at:
                          type: string
                          example: '2026-12-31 23:59:59'
                        has_password:
                          type: boolean
                          example: true
                        qr_enabled:
                          type: boolean
                          example: true
                        qr_svg_download_url:
                          type: string
                          example: 'https://shorturl.fm/short-urls/42/qr/svg'
                        qr_png_download_url:
                          type: string
                          example: 'https://shorturl.fm/short-urls/42/qr/png'
                        qr_webp_download_url:
                          type: string
                          example: 'https://shorturl.fm/short-urls/42/qr/webp'
                        created_at:
                          type: string
                          example: '2026-03-01 09:30:00'
                        updated_at:
                          type: string
                          example: '2026-03-06 11:45:00'
                        stats_url:
                          type: string
                          example: 'https://shorturl.fm/Docs-42+'
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f23696de-c811-41fd-b465-cf53539f7f4b
                      timestamp:
                        type: string
                        example: '2026-03-06T12:05:00+00:00'
                      pagination:
                        type: object
                        properties:
                          current_page:
                            type: integer
                            example: 1
                            description: 'Current page number.'
                          last_page:
                            type: integer
                            example: 3
                            description: 'Last available page number.'
                          per_page:
                            type: integer
                            example: 20
                            description: 'Number of items returned per page.'
                          total:
                            type: integer
                            example: 42
                            description: 'Total number of matching items.'
                        description: 'Pagination metadata for this endpoint.'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - 'Short URLs'
  '/api/v1/short-urls/{id}':
    get:
      summary: 'Get a short URL.'
      operationId: getAShortURL
      description: "Returns one short URL owned by the authenticated user.\nRate limit: `200/hour`, `4,800/day`, `30,000/month`."
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    id: 42
                    short_url: 'https://shorturl.fm/Docs-42'
                    long_url: 'https://example.com/very/long/path'
                    domain: shorturl.fm
                    short_code: Docs-42
                    total_clicks: 131
                    log_stats: true
                    expires_at: '2026-12-31 23:59:59'
                    has_password: true
                    qr_enabled: true
                    qr_svg_download_url: 'https://shorturl.fm/short-urls/42/qr/svg'
                    qr_png_download_url: 'https://shorturl.fm/short-urls/42/qr/png'
                    qr_webp_download_url: 'https://shorturl.fm/short-urls/42/qr/webp'
                    created_at: '2026-03-01 09:30:00'
                    updated_at: '2026-03-06 11:45:00'
                    stats_url: 'https://shorturl.fm/Docs-42+'
                  error: null
                  meta:
                    trace_id: 2bdb40b1-49fd-4abf-8b7b-26db74bc2825
                    timestamp: '2026-03-06T12:04:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 42
                      short_url:
                        type: string
                        example: 'https://shorturl.fm/Docs-42'
                      long_url:
                        type: string
                        example: 'https://example.com/very/long/path'
                      domain:
                        type: string
                        example: shorturl.fm
                      short_code:
                        type: string
                        example: Docs-42
                      total_clicks:
                        type: integer
                        example: 131
                      log_stats:
                        type: boolean
                        example: true
                      expires_at:
                        type: string
                        example: '2026-12-31 23:59:59'
                      has_password:
                        type: boolean
                        example: true
                      qr_enabled:
                        type: boolean
                        example: true
                      qr_svg_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/svg'
                      qr_png_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/png'
                      qr_webp_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/webp'
                      created_at:
                        type: string
                        example: '2026-03-01 09:30:00'
                      updated_at:
                        type: string
                        example: '2026-03-06 11:45:00'
                      stats_url:
                        type: string
                        example: 'https://shorturl.fm/Docs-42+'
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bdb40b1-49fd-4abf-8b7b-26db74bc2825
                      timestamp:
                        type: string
                        example: '2026-03-06T12:04:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Short URL not found.'
                    details: {  }
                  meta:
                    trace_id: 7b1d2f2b-d8fb-42f5-8a2d-1cdac1c4f7dd
                    timestamp: '2026-03-06T12:01:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Short URL not found.'
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 7b1d2f2b-d8fb-42f5-8a2d-1cdac1c4f7dd
                      timestamp:
                        type: string
                        example: '2026-03-06T12:01:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - 'Short URLs'
    patch:
      summary: 'Update a short URL.'
      operationId: updateAShortURL
      description: "Updates mutable properties of a short URL owned by the authenticated user.\nRate limit: `100/hour`, `2,400/day`, `10,000/month`."
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    id: 42
                    short_url: 'https://shorturl.fm/Docs-42'
                    long_url: 'https://example.com/very/long/path'
                    domain: shorturl.fm
                    short_code: Docs-42
                    total_clicks: 131
                    log_stats: true
                    expires_at: '2026-12-31 23:59:59'
                    has_password: true
                    qr_enabled: true
                    qr_svg_download_url: 'https://shorturl.fm/short-urls/42/qr/svg'
                    qr_png_download_url: 'https://shorturl.fm/short-urls/42/qr/png'
                    qr_webp_download_url: 'https://shorturl.fm/short-urls/42/qr/webp'
                    created_at: '2026-03-01 09:30:00'
                    updated_at: '2026-03-06 11:45:00'
                    stats_url: 'https://shorturl.fm/Docs-42+'
                  error: null
                  meta:
                    trace_id: 2bdb40b1-49fd-4abf-8b7b-26db74bc2825
                    timestamp: '2026-03-06T12:04:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 42
                      short_url:
                        type: string
                        example: 'https://shorturl.fm/Docs-42'
                      long_url:
                        type: string
                        example: 'https://example.com/very/long/path'
                      domain:
                        type: string
                        example: shorturl.fm
                      short_code:
                        type: string
                        example: Docs-42
                      total_clicks:
                        type: integer
                        example: 131
                      log_stats:
                        type: boolean
                        example: true
                      expires_at:
                        type: string
                        example: '2026-12-31 23:59:59'
                      has_password:
                        type: boolean
                        example: true
                      qr_enabled:
                        type: boolean
                        example: true
                      qr_svg_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/svg'
                      qr_png_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/png'
                      qr_webp_download_url:
                        type: string
                        example: 'https://shorturl.fm/short-urls/42/qr/webp'
                      created_at:
                        type: string
                        example: '2026-03-01 09:30:00'
                      updated_at:
                        type: string
                        example: '2026-03-06 11:45:00'
                      stats_url:
                        type: string
                        example: 'https://shorturl.fm/Docs-42+'
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bdb40b1-49fd-4abf-8b7b-26db74bc2825
                      timestamp:
                        type: string
                        example: '2026-03-06T12:04:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Short URL not found.'
                    details: {  }
                  meta:
                    trace_id: 7b1d2f2b-d8fb-42f5-8a2d-1cdac1c4f7dd
                    timestamp: '2026-03-06T12:01:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Short URL not found.'
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 7b1d2f2b-d8fb-42f5-8a2d-1cdac1c4f7dd
                      timestamp:
                        type: string
                        example: '2026-03-06T12:01:00+00:00'
        422:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'The given data was invalid.'
                    details:
                      validation:
                        expires_at:
                          - 'The expires at field must be a date after now.'
                  meta:
                    trace_id: 5d431ca1-5a30-4338-a799-78a141a3d2f8
                    timestamp: '2026-03-06T12:08:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'The given data was invalid.'
                      details:
                        type: object
                        properties:
                          validation:
                            type: object
                            properties:
                              expires_at:
                                type: array
                                example:
                                  - 'The expires at field must be a date after now.'
                                items:
                                  type: string
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 5d431ca1-5a30-4338-a799-78a141a3d2f8
                      timestamp:
                        type: string
                        example: '2026-03-06T12:08:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - 'Short URLs'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: 'New destination URL.'
                  example: 'https://example.com/updated-destination'
                log_stats:
                  type: boolean
                  description: 'Enable or disable click tracking.'
                  example: true
                expires_at:
                  type: string
                  description: 'New expiration timestamp, or `null` to remove it.'
                  example: '2026-12-31 23:59:59'
                qr_enabled:
                  type: boolean
                  description: 'Enable or disable QR downloads.'
                  example: true
                link_password:
                  type: string
                  description: 'Password required before redirecting. Send `null` to remove existing password.'
                  example: secret-passphrase
    parameters:
      -
        in: path
        name: id
        description: 'The short URL ID.'
        example: 42
        required: true
        schema:
          type: integer
  '/api/v1/short-urls/{id}/stats':
    get:
      summary: 'Get short URL analytics.'
      operationId: getShortURLAnalytics
      description: "Returns analytics for an owned short URL, including total clicks, recent click detail, country breakdown, and daily series.\nRate limit: `100/hour`, `2,400/day`, `10,000/month`."
      parameters:
        -
          in: query
          name: period
          description: 'Analytics preset. Supported values: `last_hour`, `last_4_hours`, `last_12_hours`, `last_24_hours`, `last_48_hours`, `last_3_days`, `last_7_days`, `last_30_days`, `last_60_days`, `last_90_days`, `last_180_days`, `last_year`, `custom`.'
          example: last_30_days
          required: false
          schema:
            type: string
            description: 'Analytics preset. Supported values: `last_hour`, `last_4_hours`, `last_12_hours`, `last_24_hours`, `last_48_hours`, `last_3_days`, `last_7_days`, `last_30_days`, `last_60_days`, `last_90_days`, `last_180_days`, `last_year`, `custom`.'
            example: last_30_days
        -
          in: query
          name: start_time
          description: 'Required when `period=custom`. Example value: `2026-02-01 00:00:00`.'
          example: null
          required: false
          schema:
            type: string
            description: 'Required when `period=custom`. Example value: `2026-02-01 00:00:00`.'
            example: null
        -
          in: query
          name: end_time
          description: 'Required when `period=custom`. Example value: `2026-02-28 23:59:59`.'
          example: null
          required: false
          schema:
            type: string
            description: 'Required when `period=custom`. Example value: `2026-02-28 23:59:59`.'
            example: null
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    short_url:
                      id: 42
                      short_url: 'https://shorturl.fm/Docs-42'
                      long_url: 'https://example.com/very/long/path'
                      domain: shorturl.fm
                      short_code: Docs-42
                      log_stats: true
                      expires_at: '2026-12-31 23:59:59'
                      has_password: true
                      qr_enabled: true
                      qr_svg_download_url: 'https://shorturl.fm/short-urls/42/qr/svg'
                      qr_png_download_url: 'https://shorturl.fm/short-urls/42/qr/png'
                      qr_webp_download_url: 'https://shorturl.fm/short-urls/42/qr/webp'
                      created_at: '2026-03-01 09:30:00'
                      updated_at: '2026-03-06 11:45:00'
                      stats_url: 'https://shorturl.fm/Docs-42+'
                    period:
                      key: last_30_days
                      from: '2026-02-05T12:00:00+00:00'
                      to: '2026-03-06T12:00:00+00:00'
                    total_clicks: 131
                    country_breakdown:
                      -
                        country_name: 'United States'
                        clicks: 84
                      -
                        country_name: Germany
                        clicks: 19
                    daily_series:
                      -
                        date: '2026-03-04'
                        clicks: 9
                      -
                        date: '2026-03-05'
                        clicks: 11
                      -
                        date: '2026-03-06'
                        clicks: 7
                    click_detail:
                      -
                        id: 901
                        short_url_id: 42
                        request_uri: 'https://shorturl.fm/Docs-42'
                        country_code: US
                        country_name: 'United States'
                        user_agent: Mozilla/5.0
                        browser: Chrome
                        crawler_name: null
                        os: macOS
                        device_type: desktop
                        referrer: 'https://example.com/newsletter'
                        is_bot: false
                        clicked_at: '2026-03-06T11:50:00.000000Z'
                      -
                        id: 900
                        short_url_id: 42
                        request_uri: 'https://shorturl.fm/Docs-42'
                        country_code: DE
                        country_name: Germany
                        user_agent: Mozilla/5.0
                        browser: Firefox
                        crawler_name: null
                        os: Linux
                        device_type: desktop
                        referrer: null
                        is_bot: false
                        clicked_at: '2026-03-06T09:12:00.000000Z'
                  error: null
                  meta:
                    trace_id: 4cb5ce2c-664f-4ec9-8f58-df1834b9d1f5
                    timestamp: '2026-03-06T12:10:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      short_url:
                        type: object
                        properties:
                          id:
                            type: integer
                            example: 42
                          short_url:
                            type: string
                            example: 'https://shorturl.fm/Docs-42'
                          long_url:
                            type: string
                            example: 'https://example.com/very/long/path'
                          domain:
                            type: string
                            example: shorturl.fm
                          short_code:
                            type: string
                            example: Docs-42
                          log_stats:
                            type: boolean
                            example: true
                          expires_at:
                            type: string
                            example: '2026-12-31 23:59:59'
                          has_password:
                            type: boolean
                            example: true
                          qr_enabled:
                            type: boolean
                            example: true
                          qr_svg_download_url:
                            type: string
                            example: 'https://shorturl.fm/short-urls/42/qr/svg'
                          qr_png_download_url:
                            type: string
                            example: 'https://shorturl.fm/short-urls/42/qr/png'
                          qr_webp_download_url:
                            type: string
                            example: 'https://shorturl.fm/short-urls/42/qr/webp'
                          created_at:
                            type: string
                            example: '2026-03-01 09:30:00'
                          updated_at:
                            type: string
                            example: '2026-03-06 11:45:00'
                          stats_url:
                            type: string
                            example: 'https://shorturl.fm/Docs-42+'
                      period:
                        type: object
                        properties:
                          key:
                            type: string
                            example: last_30_days
                          from:
                            type: string
                            example: '2026-02-05T12:00:00+00:00'
                          to:
                            type: string
                            example: '2026-03-06T12:00:00+00:00'
                      total_clicks:
                        type: integer
                        example: 131
                      country_breakdown:
                        type: array
                        example:
                          -
                            country_name: 'United States'
                            clicks: 84
                          -
                            country_name: Germany
                            clicks: 19
                        items:
                          type: object
                          properties:
                            country_name:
                              type: string
                              example: 'United States'
                            clicks:
                              type: integer
                              example: 84
                      daily_series:
                        type: array
                        example:
                          -
                            date: '2026-03-04'
                            clicks: 9
                          -
                            date: '2026-03-05'
                            clicks: 11
                          -
                            date: '2026-03-06'
                            clicks: 7
                        items:
                          type: object
                          properties:
                            date:
                              type: string
                              example: '2026-03-04'
                            clicks:
                              type: integer
                              example: 9
                      click_detail:
                        type: array
                        example:
                          -
                            id: 901
                            short_url_id: 42
                            request_uri: 'https://shorturl.fm/Docs-42'
                            country_code: US
                            country_name: 'United States'
                            user_agent: Mozilla/5.0
                            browser: Chrome
                            crawler_name: null
                            os: macOS
                            device_type: desktop
                            referrer: 'https://example.com/newsletter'
                            is_bot: false
                            clicked_at: '2026-03-06T11:50:00.000000Z'
                          -
                            id: 900
                            short_url_id: 42
                            request_uri: 'https://shorturl.fm/Docs-42'
                            country_code: DE
                            country_name: Germany
                            user_agent: Mozilla/5.0
                            browser: Firefox
                            crawler_name: null
                            os: Linux
                            device_type: desktop
                            referrer: null
                            is_bot: false
                            clicked_at: '2026-03-06T09:12:00.000000Z'
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              example: 901
                            short_url_id:
                              type: integer
                              example: 42
                            request_uri:
                              type: string
                              example: 'https://shorturl.fm/Docs-42'
                            country_code:
                              type: string
                              example: US
                            country_name:
                              type: string
                              example: 'United States'
                            user_agent:
                              type: string
                              example: Mozilla/5.0
                            browser:
                              type: string
                              example: Chrome
                            crawler_name:
                              type: string
                              example: null
                              nullable: true
                            os:
                              type: string
                              example: macOS
                            device_type:
                              type: string
                              example: desktop
                            referrer:
                              type: string
                              example: 'https://example.com/newsletter'
                            is_bot:
                              type: boolean
                              example: false
                            clicked_at:
                              type: string
                              example: '2026-03-06T11:50:00.000000Z'
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 4cb5ce2c-664f-4ec9-8f58-df1834b9d1f5
                      timestamp:
                        type: string
                        example: '2026-03-06T12:10:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Short URL not found.'
                    details: {  }
                  meta:
                    trace_id: 7b1d2f2b-d8fb-42f5-8a2d-1cdac1c4f7dd
                    timestamp: '2026-03-06T12:01:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Short URL not found.'
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 7b1d2f2b-d8fb-42f5-8a2d-1cdac1c4f7dd
                      timestamp:
                        type: string
                        example: '2026-03-06T12:01:00+00:00'
        422:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Statistics collection was not enabled for this short URL.'
                    details: {  }
                  meta:
                    trace_id: 346dcebd-1036-4624-a501-930249bcaedc
                    timestamp: '2026-03-06T12:11:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Statistics collection was not enabled for this short URL.'
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 346dcebd-1036-4624-a501-930249bcaedc
                      timestamp:
                        type: string
                        example: '2026-03-06T12:11:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - 'Short URLs'
    parameters:
      -
        in: path
        name: id
        description: 'The short URL ID.'
        example: 42
        required: true
        schema:
          type: integer
  /api/v1/tokens/rotate:
    post:
      summary: 'Rotate current token.'
      operationId: rotateCurrentToken
      description: "Creates a new personal access token and revokes the currently authenticated token in the same operation.\nThe plain-text token is only returned once.\nRate limit: `10/hour`, `50/day`, `500/month`."
      parameters: []
      responses:
        201:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    token: 18|vJKDo4jNnRkRpwFdcN5a2qM5b6e0VxYp3XGf9Q2c
                    name: deployment-script-rotated
                    token_id: 18
                    revoked_token_id: 17
                  error: null
                  meta:
                    trace_id: 3508206b-e84a-4323-8dd4-42decb202804
                    timestamp: '2026-03-09T12:12:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                        example: 18|vJKDo4jNnRkRpwFdcN5a2qM5b6e0VxYp3XGf9Q2c
                      name:
                        type: string
                        example: deployment-script-rotated
                      token_id:
                        type: integer
                        example: 18
                      revoked_token_id:
                        type: integer
                        example: 17
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 3508206b-e84a-4323-8dd4-42decb202804
                      timestamp:
                        type: string
                        example: '2026-03-09T12:12:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        422:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Token rotation requires bearer token authentication.'
                    details:
                      validation:
                        token:
                          - 'Token rotation requires bearer token authentication.'
                  meta:
                    trace_id: df62a7a0-a252-4c46-8e6d-3f7efb395dcb
                    timestamp: '2026-03-09T12:13:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Token rotation requires bearer token authentication.'
                      details:
                        type: object
                        properties:
                          validation:
                            type: object
                            properties:
                              token:
                                type: array
                                example:
                                  - 'Token rotation requires bearer token authentication.'
                                items:
                                  type: string
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: df62a7a0-a252-4c46-8e6d-3f7efb395dcb
                      timestamp:
                        type: string
                        example: '2026-03-09T12:13:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - Tokens
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: 'A label to help you identify the new token later.'
                  example: deployment-script-rotated
              required:
                - name
  '/api/v1/tokens/{id}':
    delete:
      summary: 'Delete a token.'
      operationId: deleteAToken
      description: "Revokes a token owned by the authenticated user.\nRate limit: `10/hour`, `50/day`, `500/month`."
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    success: 1
                  error: null
                  meta:
                    trace_id: 104f3d16-0c61-4307-a671-1838828be126
                    timestamp: '2026-03-06T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      success:
                        type: integer
                        example: 1
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 104f3d16-0c61-4307-a671-1838828be126
                      timestamp:
                        type: string
                        example: '2026-03-06T12:00:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Token not found.'
                    details: {  }
                  meta:
                    trace_id: 8e24b740-2546-4db8-9d1d-614f03058d9d
                    timestamp: '2026-03-06T12:02:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Token not found.'
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 8e24b740-2546-4db8-9d1d-614f03058d9d
                      timestamp:
                        type: string
                        example: '2026-03-06T12:02:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - Tokens
    parameters:
      -
        in: path
        name: id
        description: 'The token ID returned when the token was created.'
        example: 17
        required: true
        schema:
          type: integer
  /api/v1/unshorten:
    post:
      summary: 'Unshorten a URL.'
      operationId: unshortenAURL
      description: "Resolves a known short URL back to its original destination URL.\nRate limit: `100/hour`, `2,400/day`, `10,000/month`."
      parameters: []
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: true
                  data:
                    url: 'https://example.com/original-destination'
                  error: null
                  meta:
                    trace_id: 8df84d5d-5d9d-4f83-976d-8b4f4b64f2ce
                    timestamp: '2026-03-06T12:14:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      url:
                        type: string
                        example: 'https://example.com/original-destination'
                  error:
                    type: string
                    example: null
                    nullable: true
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 8df84d5d-5d9d-4f83-976d-8b4f4b64f2ce
                      timestamp:
                        type: string
                        example: '2026-03-06T12:14:00+00:00'
        401:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: Unauthenticated.
                    details: {  }
                  meta:
                    trace_id: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                    timestamp: '2026-03-08T12:30:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: Unauthenticated.
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 9f106f90-d1fc-4f85-a5dc-a2245d756590
                      timestamp:
                        type: string
                        example: '2026-03-08T12:30:00+00:00'
        403:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Please verify your email address before continuing.'
                    details:
                      status: email-verification-required
                      verify_email_url: /app/verify-email
                  meta:
                    trace_id: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                    timestamp: '2026-03-24T12:00:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Please verify your email address before continuing.'
                      details:
                        type: object
                        properties:
                          status:
                            type: string
                            example: email-verification-required
                          verify_email_url:
                            type: string
                            example: /app/verify-email
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: f0e14d9f-d652-4b3b-857c-0f5f0a9ce0f3
                      timestamp:
                        type: string
                        example: '2026-03-24T12:00:00+00:00'
        404:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Short URL was not found or blocked.'
                    details: {  }
                  meta:
                    trace_id: 5fe6a969-b3b3-4f75-be63-a4fe403ab932
                    timestamp: '2026-03-06T12:16:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Short URL was not found or blocked.'
                      details:
                        type: object
                        properties: {  }
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 5fe6a969-b3b3-4f75-be63-a4fe403ab932
                      timestamp:
                        type: string
                        example: '2026-03-06T12:16:00+00:00'
        422:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'The given data was invalid.'
                    details:
                      validation:
                        url:
                          - 'The url field format is invalid.'
                  meta:
                    trace_id: 8505ac29-db5d-4534-a729-7fd71b34ccbf
                    timestamp: '2026-03-06T12:15:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'The given data was invalid.'
                      details:
                        type: object
                        properties:
                          validation:
                            type: object
                            properties:
                              url:
                                type: array
                                example:
                                  - 'The url field format is invalid.'
                                items:
                                  type: string
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 8505ac29-db5d-4534-a729-7fd71b34ccbf
                      timestamp:
                        type: string
                        example: '2026-03-06T12:15:00+00:00'
        429:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  data: null
                  error:
                    message: 'Too Many Attempts.'
                    details:
                      retry_after_seconds: 3600
                      rate_limit_reset_at_unix: 1772985600
                  meta:
                    trace_id: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                    timestamp: '2026-03-08T12:31:00+00:00'
                properties:
                  success:
                    type: boolean
                    example: false
                  data:
                    type: string
                    example: null
                    nullable: true
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'Too Many Attempts.'
                      details:
                        type: object
                        properties:
                          retry_after_seconds:
                            type: integer
                            example: 3600
                          rate_limit_reset_at_unix:
                            type: integer
                            example: 1772985600
                  meta:
                    type: object
                    properties:
                      trace_id:
                        type: string
                        example: 2bb87fd5-4128-48dc-88ca-f3a62e2be9a7
                      timestamp:
                        type: string
                        example: '2026-03-08T12:31:00+00:00'
      tags:
        - Utilities
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: 'The short URL to expand.'
                  example: 'https://shorturl.fm/AbCdE-1'
              required:
                - url
  /api/v1/internal/block-short-urls:
    post:
      summary: ''
      operationId: postApiV1InternalBlockShortUrls
      description: ''
      parameters: []
      responses: {  }
      tags:
        - Endpoints
