---
title: "Get a widget"
method: GET
path: "/v1/sites/{site_id}/widgets/{widget_id}"
tags: ["Widgets"]
---

# Get a widget

`GET /v1/sites/{site_id}/widgets/{widget_id}`

## Request

- Base URL: `https://api.getsitecontrol.com`
- URL: `https://api.getsitecontrol.com/v1/sites/{site_id}/widgets/{widget_id}`
- Auth: HTTP bearer

One widget with everything List widgets gives, plus its `content` (pages, texts, fields, buttons), the `notification_emails` its responses are sent to, and who created and last edited it.

## Path parameters

- `site_id` integer, required
- `widget_id` integer, required: Widget id from List widgets

## Response `200`

Successful Response

- WidgetCard
  - `id` integer, required
  - `name` string, nullable
  - `headline` string, nullable: The widget's first headline, plain text; null when it has none
  - `layout` 'modal' | 'bar' | 'panel' | 'slide_in' | 'sidebar' | 'fullscreen' | 'inline' | 'other', required: Where the widget sits on the page, named as in the admin. modal: a window centred over the page. bar: a strip across the top or bottom of the page. panel: a box attached to the bottom of the screen, opened from its header. slide_in: a box that slides in from a corner. sidebar: a panel attached to the left or right edge of the screen. fullscreen: covers the whole screen. inline: placed inside the page content. other: a layout the admin no longer offers. "Pop-up" is not a layout: users call any widget a pop-up.
  - `is_active` boolean, required
  - `ab_test_group` WidgetAbTestGroup
    - `id` integer, required
    - `name` string, nullable
  - `folder` Folder, required
    - `id` integer, required: 0 is General, where items outside any folder are
    - `name` string, required
  - `actions` string[], required: Event types the widget can produce besides show and close
  - `features` WidgetFeatures, required
    - `collects_email` boolean, required: Has an e-mail field
    - `collects_phone` boolean, required: Has a phone field
    - `has_coupon` boolean, required: A button copies or applies a discount code
    - `has_game` boolean, required: Has a game: a wheel, a scratch card or a reveal
    - `has_countdown` boolean, required: Has a countdown timer
    - `has_teaser` boolean, required: Has a teaser, the small tab shown before or after it
    - `captcha` boolean, required: reCAPTCHA checks its form submits
    - `double_opt_in` boolean, required: A new subscriber confirms the address by e-mail first
    - `email_quality_filter` boolean, required: Submits with disposable or untrusted e-mail addresses are rejected
    - `notifications` boolean, required: Responses are e-mailed: switched on, with a recipient
    - `in_ab_test` boolean, required: In an A/B test, named in `ab_test_group`
    - `has_integration` boolean, required: An integration, webhook or Zapier switched on sends its responses
    - `has_draft` boolean, required: You have a draft of it with unsaved changes, see `draft`
  - `targeting` WidgetTargeting, required
    - `is_complete` boolean, required: False when some rules could not be read into the blocks below
    - `warnings` string[], required: Informational notes; wording is not stable, do not parse
    - `pages` TargetingPages
      - `include` string[], required
      - `exclude` string[], required
    - `audience` TargetingAudience
      - `match` 'all' | 'any', required: all: every item must hold; any: one is enough.
      - `segments` TargetingAudienceSegment[], required
        - `match` 'all' | 'any', required: all: every item must hold; any: one is enough.
        - `conditions` TargetingAudienceCondition[], required
          - `key` string, required
          - `operator` 'is' | 'is_not' | 'less_than' | 'greater_than' | 'starts_with' | 'does_not_start_with' | 'ends_with' | 'does_not_end_with' | 'contains' | 'does_not_contain' | 'matches' | 'does_not_match' | 'has_any_value' | 'is_undefined' | 'matches_url' | 'does_not_match_url' | 'matches_ip' | 'does_not_match_ip' | 'any_of' | 'none_of' | 'during' | 'not_during', required: How a condition tests its value; any_of and none_of take a list, during and not_during a range, has_any_value and is_undefined no value.
          - `value` unknown
          - `subject` string, nullable
    - `start` TargetingStart
      - `mode` 'immediate' | 'programmatically' | 'triggers', required: immediate: on page load; programmatically: only when the site's code shows it; triggers: when one of `triggers` fires.
      - `triggers` TargetingTrigger[], required
        - `type` 'exit_intent' | 'scroll_percent' | 'time_on_page_seconds' | 'time_on_site_seconds' | 'inactivity_seconds' | 'add_to_cart' | 'remove_from_cart' | 'automatic' | 'display_time_seconds', required: What fires a show or a hide; a *_seconds or *_percent trigger carries its threshold in `value`.
        - `value` union
          - integer
          - number
    - `hide` TargetingHide
      - `triggers` TargetingTrigger[], required
        - `type` 'exit_intent' | 'scroll_percent' | 'time_on_page_seconds' | 'time_on_site_seconds' | 'inactivity_seconds' | 'add_to_cart' | 'remove_from_cart' | 'automatic' | 'display_time_seconds', required: What fires a show or a hide; a *_seconds or *_percent trigger carries its threshold in `value`.
        - `value` union
          - integer
          - number
    - `stop` TargetingStop
      - `rules` TargetingStopRule[], required
        - `event` 'action' | 'close' | 'hide' | 'show' | 'show_count', required: The visitor's event after which the widget stops showing; close and show are named for their event. action: after the visitor submits it or clicks its button. hide: after a hide trigger hides it. show_count: after `count` shows.
        - `mode` 'forever' | 'duration': forever: never again after the event; duration: not for `duration_seconds` after it.
        - `duration_seconds` number, nullable
        - `count` integer, nullable
    - `schedule` TargetingSchedule
      - `match` 'all' | 'any', required: all: every item must hold; any: one is enough.
      - `segments` TargetingScheduleSegment[], required
        - `match` 'all' | 'any', required: all: every item must hold; any: one is enough.
        - `conditions` TargetingScheduleCondition[], required
          - `key` 'date' | 'time' | 'weekday', required: date: a range of days; time: a range of hours in a time zone; weekday: days of the week, 0 is Sunday.
          - `operator` 'is' | 'is_not' | 'less_than' | 'greater_than' | 'starts_with' | 'does_not_start_with' | 'ends_with' | 'does_not_end_with' | 'contains' | 'does_not_contain' | 'matches' | 'does_not_match' | 'has_any_value' | 'is_undefined' | 'matches_url' | 'does_not_match_url' | 'matches_ip' | 'does_not_match_ip' | 'any_of' | 'none_of' | 'during' | 'not_during', required: How a condition tests its value; any_of and none_of take a list, during and not_during a range, has_any_value and is_undefined no value.
          - `value` union, required
            - TargetingTimeRange
              - …
            - TargetingDateRange
              - …
            - integer[]
  - `draft` WidgetDraftState
    - `state` 'new' | 'draft' | 'synced', required: new: started with create_widget_draft and not saved yet; the widget exists only in this draft. draft: your unsaved changes over the saved widget. synced: the draft matches the saved widget.
    - `revision` integer, nullable: The draft's revision: 1 when it started, one more per change; null when you have no draft of this widget
    - `saved_changed` boolean, required: true: the widget was saved after your draft started, and saving would replace that save
    - `saved_by` string, nullable: Who made that save, when saved_changed; e-mail or name
    - `saved_at` string, date-time, nullable: When they saved, when saved_changed
    - `started_at` string, date-time, nullable: When this draft started; a draft that started before this conversation is unfinished work, maybe yours
    - `updated_at` string, date-time, nullable: Last change to the draft
    - `preview_url` string, nullable: One permanent page per widget: your draft while it has unsaved changes, the saved widget otherwise, refreshed as you edit; null where live previews are not set up
  - `warnings` string[], required: Informational notes about the widget itself; wording is not stable, do not parse
  - `created_at` string, date-time, nullable
  - `updated_at` string, date-time, nullable: Last change of the widget itself; a move to another folder does not change it
  - `edited_at` string, date-time, nullable: Last change made in the editor
  - `truncated` string[]: Parts shortened in the list, as paths; the card has them whole. Empty when nothing was cut
  - `content` WidgetContent, required
    - `is_supported` boolean, required: False for widgets whose content cannot be read; lists are empty
    - `pages` WidgetContentPage[], required
      - `ref` string, nullable
      - `blocks` WidgetContentBlock[], required
        - `kind` 'header' | 'page' | 'group' | 'text' | 'button' | 'field' | 'marquee' | 'image' | 'floating_image' | 'progress' | 'countdown' | 'other', required: What a content block is. header: the panel header above every page; page: a page, `label` is its name; group: a container of other blocks; text: copy in `text`; button: with its text in `label`; field: a form field, games included, see `type`; marquee: a scrolling line, copy in `text`; image: an Image, in the flow of the content; floating_image: a Floating image, placed over the page at an offset from a corner; progress: a progress bar towards a goal, no copy published; countdown: a timer to a date or for a duration, no copy published; other: any other block, no copy published.
        - `surface` 'widget' | 'page' | 'teaser', required: widget: the panel header, shown with no page in particular. page: a block of the page `page_ref`. teaser: a block of the teaser.
        - `ref` string, nullable: This block's ref, as widget config reads and edits name it
        - `page_ref` string, nullable
        - `parent_ref` string, nullable: The block this one is nested in
        - `text` string, nullable: Full plain text, not HTML
        - `label` string, nullable: Visible label of a field or a button
        - `name` string, nullable: Technical name of a field, its `name` in responses
        - `type` 'email' | 'text' | 'textarea' | 'tel' | 'phone' | 'hidden' | 'flag' | 'select' | 'radio' | 'checkbox' | 'rating' | 'nps' | 'reveal' | 'scratch' | 'wheel' | 'other': Type of a form field, as the editor offers it (email, text, textarea, hidden, select, radio, rating, nps and the ones below). tel: a plain phone input; phone: one with a country selector; flag: a single checkbox; checkbox: a group of checkboxes; reveal, scratch, wheel: games; the answer is the drawn prize, its `name` is the prize code; other: any other field, or one the widget's current form no longer describes.
        - `options` WidgetContentOption[], nullable: Choices of a select, radio or checkbox field, or the prizes of a game (`name` is the prize code)
          - `name` string, required: What a response stores: `name` of an option in its `value`
          - `label` string, nullable: Visible text, plain; null when the option shows none
        - `max` integer, nullable: Top of a rating (1 to max) or an NPS (0 to max) scale; a response stores the answer as the option name, e.g. "4"
        - `is_required` boolean, nullable
    - `teaser` WidgetContentBlock[], required
      - `kind` 'header' | 'page' | 'group' | 'text' | 'button' | 'field' | 'marquee' | 'image' | 'floating_image' | 'progress' | 'countdown' | 'other', required: What a content block is. header: the panel header above every page; page: a page, `label` is its name; group: a container of other blocks; text: copy in `text`; button: with its text in `label`; field: a form field, games included, see `type`; marquee: a scrolling line, copy in `text`; image: an Image, in the flow of the content; floating_image: a Floating image, placed over the page at an offset from a corner; progress: a progress bar towards a goal, no copy published; countdown: a timer to a date or for a duration, no copy published; other: any other block, no copy published.
      - `surface` 'widget' | 'page' | 'teaser', required: widget: the panel header, shown with no page in particular. page: a block of the page `page_ref`. teaser: a block of the teaser.
      - `ref` string, nullable: This block's ref, as widget config reads and edits name it
      - `page_ref` string, nullable
      - `parent_ref` string, nullable: The block this one is nested in
      - `text` string, nullable: Full plain text, not HTML
      - `label` string, nullable: Visible label of a field or a button
      - `name` string, nullable: Technical name of a field, its `name` in responses
      - `type` 'email' | 'text' | 'textarea' | 'tel' | 'phone' | 'hidden' | 'flag' | 'select' | 'radio' | 'checkbox' | 'rating' | 'nps' | 'reveal' | 'scratch' | 'wheel' | 'other': Type of a form field, as the editor offers it (email, text, textarea, hidden, select, radio, rating, nps and the ones below). tel: a plain phone input; phone: one with a country selector; flag: a single checkbox; checkbox: a group of checkboxes; reveal, scratch, wheel: games; the answer is the drawn prize, its `name` is the prize code; other: any other field, or one the widget's current form no longer describes.
      - `options` WidgetContentOption[], nullable: Choices of a select, radio or checkbox field, or the prizes of a game (`name` is the prize code)
        - `name` string, required: What a response stores: `name` of an option in its `value`
        - `label` string, nullable: Visible text, plain; null when the option shows none
      - `max` integer, nullable: Top of a rating (1 to max) or an NPS (0 to max) scale; a response stores the answer as the option name, e.g. "4"
      - `is_required` boolean, nullable
  - `notification_emails` string[], required: Where responses are e-mailed; whether they are is `features.notifications`
  - `created_by` Author: A user of the account, as the admin shows them.
    - `id` integer, nullable: null for Support or for a user who was deleted
    - `name` string, nullable: null when the user has no name
    - `email` string, nullable: The user's sign-in e-mail; null for Support
  - `edited_by` Author: A user of the account, as the admin shows them.
    - `id` integer, nullable: null for Support or for a user who was deleted
    - `name` string, nullable: null when the user has no name
    - `email` string, nullable: The user's sign-in e-mail; null for Support

## Other responses

- `400`: Unsupported GSC-Version
- `401`: Missing or invalid API key or access token
- `403`: Access denied
- `404`: Not found
- `422`: Validation failed
- `429`: Rate limited
- `503`: Temporarily unavailable; retry later

---

[API](https://skmtc.dev/getsitecontrol/apis/getsitecontrol-public-api.md) - [All operations](https://skmtc.dev/getsitecontrol/apis/getsitecontrol-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getsitecontrol/apis/getsitecontrol-public-api/revisions/084fcad80e75?raw)
