---
title: "Create a smart tip"
method: POST
path: "/smart-tips"
tags: ["Smart Tips"]
---

# Create a smart tip

`POST /smart-tips`

## Request

- Base URL: `https://api.produktly.com/api/v1`
- URL: `https://api.produktly.com/api/v1/smart-tips`
- Auth: HTTP bearer

Creates the tip as a draft. Pass active: true to publish immediately — the tip must have settings.cssSelector and targeting set, otherwise it stays a draft and the response note explains why. The response includes a dashboardUrl for reviewing the tip in the builder.

## Request body

- object
  - `name` string, required: Internal name
  - `title` string: Card title (plain text)
  - `content` string: Card body as HTML
  - `settings` object, required
    - `cssSelector` string, required: CSS selector of the element the tip anchors to. Required — without it nothing renders
    - `displayOn` 'click' | 'hover' | 'focus' | 'beacon_click' | 'beacon_hover': What opens the tip. Default "click"
    - `hideWhen` 'click' | 'mouse_leaves': Only honored for hover triggers. Default "click"
    - `displayBeacon` boolean: Show the beacon dot. Default true
    - `beaconStyle` 'pulsating_point' | 'question_mark' | 'info_icon'
    - `offsetX` number: Beacon X offset in px. Must be a number — the widget ignores numeric strings
    - `offsetY` number: Beacon Y offset in px. Must be a number — the widget ignores numeric strings
    - `orientElement` 'element' | 'beacon': Default "element"
    - `cardOrientation` 'auto' | 'top' | 'bottom' | 'left' | 'right'
    - `hideWhenOffPage` boolean
    - `width` integer: Card width px. Default 356
    - `height` integer
    - `overrideZIndex` integer
    - `action` 'none' | 'open_url' | 'start_tour'
    - `actionText` string
    - `actionUrl` string: Required when action=open_url
    - `openActionUrlInNewTab` boolean
    - `tourId` integer: Required when action=start_tour
    - `secondaryAction` 'none' | 'open_url' | 'start_tour'
    - `secondaryActionText` string
    - `secondaryActionUrl` string
    - `secondaryOpenActionUrlInNewTab` boolean
    - `secondaryTourId` integer
    - `actionPosition` 'left' | 'center' | 'right'
    - `themeColor` string: Overridden by an attached theme
    - `textColor` string
    - `display` 'once' | 'always' | 'custom': How often it shows. Default "once"
    - `displayTimes` integer: Required when display="custom"
  - `targeting` union: Where the tip shows. Without targeting it can never show
    - object
      - `showOnAllPages` true, required
    - object
      - `rules` object[], required
        - `type` union, required
          - 'url' | 'current_time' | 'time_of_day' | 'day_of_week' | 'location' | 'language' | 'produktly_user_created_at' | 'device_type' | 'screen_width' | 'screen_height' | 'produktly_user_visit_count' | 'produktly_user_days_active'
          - string
          - string
        - `comparisonOperator` 'equals' | 'not_equal' | 'contains' | 'no_contains' | 'starts_with' | 'ends_with' | 'one_of' | 'not_one_of' | 'greater' | 'greater_eq' | 'less' | 'less_eq' | 'exists' | 'not_exists' | 'time_ago' | 'within_last' | 'between', required
        - `value` union
          - string
          - number
          - union[]
            - union
              - …
          - object
            - `value` integer, required
            - `unit` 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years', required
      - `logicalOperator` 'AND' | 'OR' | 'and' | 'or': How multiple rules combine. Default "AND".
    - object
      - `userSegmentIds` integer[], required
  - `themeId` integer
  - `folderId` integer
  - `active` boolean: Publish immediately. Needs settings.cssSelector and targeting; otherwise saved as a draft and the response note explains why

## Response `201`

Created smart tip

- SmartTip
  - `id` integer, required
  - `name` string, required
  - `active` boolean, required
  - `createdAt` string, date-time, required
  - `updatedAt` string, date-time, required
  - `folderId` integer, nullable, required
  - `themeId` integer, nullable, required
  - `title` string, nullable, required
  - `content` string, nullable, required
  - `settings` object, required
  - `rules` object[], required
  - `ruleLogicalOperator` string, nullable, required
  - `dashboardUrl` string, required
  - `note` string

## Other responses

- `400`: Validation error
- `401`: Unauthorized
- `403`: Plan limit reached
- `429`: Rate limit exceeded

---

[API](https://skmtc.dev/produktly/apis/produktly-api.md) · [All operations](https://skmtc.dev/produktly/apis/produktly-api/llms.txt) · [OpenAPI document](https://skmtc.dev/produktly/apis/produktly-api/revisions/fd942a97a7d1?raw)
