English EN
API Reference
API Reference

Products and files

Update product

PATCH / v1 / products / {product_id}

Changes the fields that you send. All other fields stay.

  • status live publishes the product. This needs a finished account setup and content. draft hides it.
  • content replaces all content blocks. Call GET /v1/products/{product_id} first and send back the blocks that should stay, with their file_id.
  • null removes an optional value: compare_at_price, intro_price, limited_offer, dates, limits, url_slug and banner.
  • course_id changes the course that buyers of a course product get.

The fields have the same names and formats as in GET /v1/products/{product_id}.

Changes at once MCP tool update_product

Authorization

  • Authorization string header required

    Bearer tnt_… · A personal API key (tnt_...). Create it in the Tentary app on the page AI & API. Introduction

Path parameters

  • product_id integer required

    The id from list_products.

    min 1 Example: 105

Body application/json

  • status string

    live = buyers can see and buy it. draft = hidden.

    Allowed values: draftlive

  • name string

    Product name.

    min length 1 max length 255

  • price number | string can be null

    Amount in the account currency, like 49 or 19.99. 0 = free. Paid prices start at 1.00. For external: the price shown on the card.

    min 0 pattern ^[0-9]{1,9}(\.[0-9]{1,2})?$

  • billing string

    Default one_time.

    Allowed values: one_timesubscription

  • billing_interval_months integer can be null

    subscription: months between payments, default 1.

    min 1 max 12

  • intro_price number | string can be null

    subscription: price of the first period, less than price.

    min 0 pattern ^[0-9]{1,9}(\.[0-9]{1,2})?$

  • installment_plans array of object

    one_time: payment plans that buyers can choose. [] removes them.

    max items 5

    Show 2 fields Hide fields
    • count integer required

      min 2 max 100

    • amount number | string required

      Per installment. Amount in the account currency, like 49 or 19.99.

      pattern ^[0-9]{1,9}(\.[0-9]{1,2})?$

  • compare_at_price number | string can be null

    one_time: crossed-out old price, higher than price. While a limited_offer runs, price is the crossed-out price instead; compare_at_price shows again when the offer ends.

    pattern ^[0-9]{1,9}(\.[0-9]{1,2})?$

  • limited_offer object can be null

    one_time: a lower price for a time. While it runs, the sales page and the checkout show price crossed out and the offer price. Times with a zone; convert the seller's local time with timezone from get_account_overview.

    Show 4 fields Hide fields
    • price number | string required

      pattern ^[0-9]{1,9}(\.[0-9]{1,2})?$

    • starts_at string required

      Like 2026-11-26T23:00:00Z.

    • ends_at string required

      Like 2026-11-30T22:59:00Z.

    • countdown object can be null

      A countdown to ends_at on the sales page and the checkout while the offer runs (made by JavaScript in the browser). null = none. Left out = unchanged. An object replaces the whole countdown.

      Show 4 fields Hide fields
      • style string required

        classic and slim: a bar at the top (sticky: it stays while buyers scroll). card_*: a box next to the price.

        Allowed values: classicclassic_stickyslimslim_stickycard_classiccard_slimcard_special_1

      • text string can be null

        Short text in the countdown, like "Launch price ends in".

        max length 255

      • color string

        Background, hex like #ff4400 (default).

      • secondary_color string can be null

        Bars: the text color (default white). Cards: the card background (default #1a1a1a).

  • description_html string

    Sales page text as HTML (p, h1-h4, strong, em, ul, ol, li, a, img, blockquote; a with class "button" is a button). The page always has its own buy button. A buy button in the text links to the url of the product + "/checkout" (create_product and get_product give url); there is no #buy anchor.

    max length 200000

  • checkout_description_html string

    Extra text only on the checkout page, HTML. Not for external.

    max length 20000

  • checkout_banner_url string can be null

    Banner image only on the checkout page, above the product title (it replaces the small product image). Recommended 1200 x 300 px. The image_url from finish_image, or a public image URL that Tentary copies. Not for external.

    max length 2048

  • images array of string

    Product images on the sales page as https URLs: the image_url from finish_image (for an image on your disk), or a public image URL that Tentary copies (PNG, JPG, GIF, WebP, at most 10 MB). The first is the cover. YouTube links show as video. Replaces all images.

    max length 2048 max items 20

  • content array of object

    download: what buyers get, in order. booking: what buyers get in addition to the appointment. Replaces all content.

    max items 100

    Show 8 fields Hide fields
    • type string required

      text: formatted text. image: shows the image. video: an uploaded video in the player (streamed, converted some minutes after its first use). audio: an audio player. file: a download. video_embed: a YouTube, Vimeo or Loom video. button: a link button. image, video, audio and file need file_id. Type, name and description are stored with the file: one file shows the same way in every product and lesson.

      Allowed values: textimagevideoaudiofilevideo_embedbutton

    • html string

      text: the text as HTML (p, h1-h4, strong, em, ul, ol, li, a, img, blockquote). Placeholders for the buyer: %FIRST_NAME%, %FULL_NAME%, %EMAIL%, %PRODUCT_TITLE%, %VARIANT_TITLE%, %ORDER_ID%, %ACCESS_LINK[Text]%, %ACCESS_LINK_BUTTON[Text]%, %SELLER_NAME%, %SELLER_SUPPORT_EMAIL%; bookings also %ORDER_BOOKING_FROM%, %ORDER_BOOKING_TO%, %ORDER_BOOKING_ZOOM_LINK%.

      max length 65535

    • url string

      video_embed: YouTube, Vimeo or Loom link. button: the link target.

      max length 2048

    • label string

      button: the button text.

      max length 250

    • file_id integer

      image, video, audio, file: a file from upload_file, or a file_id from get_product or get_lesson content.

      min 1

    • name string

      image, video, audio, file: the name of the file (file: shown above the download).

      min length 1 max length 250

    • description string

      file: plain text under the download. audio: the title above the player.

      max length 65535

    • folder string can be null

      Optional folder name. Blocks with the same folder show together. Not in lessons.

      max length 250

  • link_url string can be null

    link: the link that buyers get.

    max length 2048

  • access_text_html string can be null

    link: text that buyers see after purchase. bundle: extra details for the buyers. HTML. Takes the placeholders of text blocks.

    max length 65535

  • bundle_items array of object can be null

    bundle: the products that buyers get, from list_products (live or draft; no bundles or bookings). For a product with variants, give the variant_id of one variant. Replaces the list. Needed to go live.

    max items 100

    Show 2 fields Hide fields
    • product_id integer required

      min 1

    • variant_id integer can be null

      Only for a product with variants.

      min 1

  • external_url string can be null

    external: where buyers buy it.

    max length 2048

  • course_id integer

    course: the course that buyers get (from list_courses or create_course). Needed to go live.

    min 1

  • variants array of object can be null

    download, link and course: options that buyers choose at checkout, each with its own name, price, stock and content (download: content, link: link_url and access_text_html, course: course_id). Replaces the list: a variant with id stays and changes (fields that you leave out stay), one without id is new, a variant that is not in the list is removed (its buyers keep access). [] or null removes all variants. With variants, price is the lowest variant price; billing must be one_time, without installment_plans, limited_offer and compare_at_price; a download product has no content of its own.

    max items 50

    Show 8 fields Hide fields
    • id integer

      An existing variant (from get_product). Leave out for a new variant.

      min 1

    • name string

      Needed for a new variant.

      min length 1 max length 255

    • price number | string

      Amount in the account currency, like 49 or 19.99. 0 = free. Needed for a new variant.

      min 0 pattern ^[0-9]{1,9}(\.[0-9]{1,2})?$

    • stock_limit integer can be null

      How many can be sold. null or 0 = no limit.

      min 0

    • content array of object

      download: what buyers of this variant get. Replaces its content.

      max items 100

      Show 8 fields Hide fields
      • type string required

        text: formatted text. image: shows the image. video: an uploaded video in the player (streamed, converted some minutes after its first use). audio: an audio player. file: a download. video_embed: a YouTube, Vimeo or Loom video. button: a link button. image, video, audio and file need file_id. Type, name and description are stored with the file: one file shows the same way in every product and lesson.

        Allowed values: textimagevideoaudiofilevideo_embedbutton

      • html string

        text: the text as HTML (p, h1-h4, strong, em, ul, ol, li, a, img, blockquote). Placeholders for the buyer: %FIRST_NAME%, %FULL_NAME%, %EMAIL%, %PRODUCT_TITLE%, %VARIANT_TITLE%, %ORDER_ID%, %ACCESS_LINK[Text]%, %ACCESS_LINK_BUTTON[Text]%, %SELLER_NAME%, %SELLER_SUPPORT_EMAIL%; bookings also %ORDER_BOOKING_FROM%, %ORDER_BOOKING_TO%, %ORDER_BOOKING_ZOOM_LINK%.

        max length 65535

      • url string

        video_embed: YouTube, Vimeo or Loom link. button: the link target.

        max length 2048

      • label string

        button: the button text.

        max length 250

      • file_id integer

        image, video, audio, file: a file from upload_file, or a file_id from get_product or get_lesson content.

        min 1

      • name string

        image, video, audio, file: the name of the file (file: shown above the download).

        min length 1 max length 250

      • description string

        file: plain text under the download. audio: the title above the player.

        max length 65535

      • folder string can be null

        Optional folder name. Blocks with the same folder show together. Not in lessons.

        max length 250

    • link_url string can be null

      link: the link that buyers of this variant get.

      max length 2048

    • access_text_html string can be null

      link: text that buyers of this variant see after purchase, HTML. Takes the placeholders of text blocks.

      max length 65535

    • course_id integer

      course: the course that buyers of this variant get. Needed for a new variant.

      min 1

  • marketing_emails boolean

    Subscribe buyers to the marketing e-mails (always on for newsletter).

  • ebook boolean

    Treat as e-publication (e-book) for VAT.

  • pdf_stamp boolean

    Stamp PDFs with the buyer's e-mail address.

  • login_protection boolean

    Buyers must log in to open the product.

  • show_in_search boolean

    Show the sales page in Google.

  • hide_in_shop boolean

    Do not show the product on the shop page.

  • coupon_field boolean

    Show the coupon field at checkout (default true).

  • stock_limit integer can be null

    How many can be sold. null or 0 = no limit.

    min 0

  • buy_button_text string

    Text of the buy button. Empty = default.

    max length 30

  • url_slug string can be null

    Own URL part: shop URL/p/<url_slug>. Lowercase letters, digits and hyphens.

    max length 120

  • access_days integer can be null

    Access ends this many days after purchase (3 to 9999). null or 0 = no end.

    min 0 max 9999

  • access_starts_on string can be null

    Buyers get access from this day at the earliest (for example the start of a program). Before it they wait. null = at once. Not for newsletter and external.

    pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}$

  • lead_magnet boolean

    A free product that grows the e-mail list: buyers first confirm the marketing e-mails, then they get the product. Needs price 0 and billing one_time, and turns on marketing_emails. Not for newsletter, booking and external.

  • withdrawal_days integer

    Withdrawal period shown at checkout.

    Allowed values: 01430

  • available_from string can be null

    First day of sale.

    pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}$

  • available_until string can be null

    Last day of sale.

    pattern ^[0-9]{4}-[0-9]{2}-[0-9]{2}$

Response

Fields of the answer with status 200. Errors always have the same format, see Errors.

The short form. get_product has all fields.

  • id integer

    The ID.

  • name string

    The name.

  • type string

    The type.

    Allowed values: downloadlinknewsletterbookingcoursebundleexternal

  • status string

    archived = deleted.

    Allowed values: livedraftarchived

  • url string<uri>

    Sales page.

  • admin_url string<uri>

    The page in the Tentary app.

  • note string

    What to do next.

Start typing to search.