Tiquo
API and AuthenticationHosted Package

Data attributes and JavaScript API

Use HTML attributes or JavaScript methods to add Tiquo login, customer fields, orders, bookings, and analytics events

Data attributes and JavaScript API

The Hosted Package works with plain HTML. This makes it compatible with website builders that let you add custom attributes to elements.

Passwordless login

Use one form and one submit button for the full passwordless flow. The first submit sends the OTP email. The second submit verifies the OTP and signs the customer in.

<form data-tiquo-form="passwordless-login">
  <div data-tiquo-passwordless="step-1">
    <input data-tiquo-member="email" type="email" name="email" placeholder="Email" required />
  </div>

  <div data-tiquo-passwordless="step-2">
    <input data-tiquo-member="token" type="text" name="token" inputmode="numeric" placeholder="Code" required />
  </div>

  <p data-tiquo-message></p>
  <button
    data-tiquo-passwordless-button="Sign in"
    data-tiquo-passwordless-send-loading="Sending..."
    data-tiquo-passwordless-verify-loading="Signing in..."
  >
    Send code
  </button>
</form>

When the form is submitted for the first time, Tiquo sends a one-time code to the email address. When the code field is filled and submitted, the customer is signed in.

The Hosted Package hides step-2 until the OTP has been sent, then hides step-1 if you use the optional data-tiquo-passwordless="step-1" wrapper. Inputs inside a hidden step are disabled automatically so browser form validation does not block submission.

Passwordless login and signup forms are automatically hidden after the customer is signed in. They become visible again after logout.

The email field must use data-tiquo-member="email" and the OTP field must use data-tiquo-member="token". In Webflow, make sure the hidden OTP field is not configured as an email input. Use a text input with numeric input mode for the OTP code.

Webflow setup checklist

  • Put both steps inside the same Webflow form.
  • Use one submit button for both steps.
  • Add data-tiquo-form="passwordless-login" to the form.
  • Wrap the email input in an element with data-tiquo-passwordless="step-1".
  • Wrap the OTP input in an element with data-tiquo-passwordless="step-2".
  • Set the email input to type="email", name="email", and data-tiquo-member="email".
  • Set the OTP input to type="text", name="token", and data-tiquo-member="token".
  • Do not use type="email" or name="email" on the OTP input.
  • Add data-tiquo-passwordless-button="Sign in" to the submit button if you want the button text to change after the OTP is sent.
  • Add data-tiquo-passwordless-send-loading="Sending..." to show loading text while the OTP email is being sent.
  • Add data-tiquo-passwordless-verify-loading="Signing in..." to show loading text while the OTP code is being verified.
  • Use data-tiquo-passwordless-loading="Loading..." if both steps should use the same loading text.
  • Use ?v=1.1.15 or newer in the Hosted Package script URL so Tiquo intercepts submit buttons, Enter key submits, and form submits before Webflow can show its default success message.

If Webflow switches to its default Thank you! Your submission has been received! success state, the form submit is being handled by Webflow instead of only by Tiquo. Use ?v=1.1.15 or newer and keep data-tiquo-form="passwordless-login" on the actual Webflow form element.

If Webflow shows An invalid form control with name='email' is not focusable, the hidden OTP field is usually misconfigured as an email field or the hidden step contains a required control that is not disabled. Use the script URL with ?v=1.1.15 or newer so hidden-step inputs are disabled automatically.

Show or hide content by auth state

<div data-tiquo-show="logged-in">
  Visible to signed-in customers.
</div>

<div data-tiquo-show="logged-out">
  Visible to visitors who are not signed in.
</div>

You can set these elements to display: none in Webflow to prevent a visible flash before the Hosted Package finishes checking the session. Tiquo will show the matching element again when it should be visible. If the element needs a specific display type, add data-tiquo-display="flex", data-tiquo-display="grid", or another CSS display value. Use ?v=1.1.15 or newer for this behaviour.

Log out button

Add data-tiquo-logout to a button or link to sign the customer out.

<button
  data-tiquo-logout
  data-tiquo-logout-loading="Logging out..."
>
  Log out
</button>

Optional attributes:

  • data-tiquo-logout-loading="Logging out..." changes the button text while logout is running.
  • data-tiquo-logout-redirect="/login" redirects after logout completes.

Use data-tiquo-show="logged-in" on the button or its wrapper if it should only be visible to signed-in customers.

Use data-tiquo-wallet-card to link a signed-in customer to an Apple Wallet or Google Wallet card. The attribute value is the wallet card design name from the dashboard.

<a
  data-tiquo-wallet-card="member-card"
  data-tiquo-wallet-type="apple"
>
  Add to Apple Wallet
</a>

<a
  data-tiquo-wallet-card="member-card"
  data-tiquo-wallet-type="google"
>
  Add to Google Wallet
</a>

Optional attributes:

  • data-tiquo-wallet-type="apple" links directly to the Apple Wallet install flow.
  • data-tiquo-wallet-type="google" links directly to the Google Wallet install flow.
  • Omit data-tiquo-wallet-type to link to the general wallet card install page.
  • data-tiquo-wallet-card-loading="Loading..." changes the text while the link is being resolved.

The design name must match the wallet card design name configured in the dashboard. If the account has multiple wallet card designs, use one link per design name.

Advanced sites can also call:

const links = await window.Tiquo.getWalletCardLinks({
  designName: "member-card"
});

console.log(links.appleWalletUrl);
console.log(links.googleWalletUrl);

Render customer fields

<span data-tiquo-customer="firstName"></span>
<span data-tiquo-customer="lastName"></span>
<span data-tiquo-customer="displayName"></span>
<span data-tiquo-customer="email"></span>
<span data-tiquo-customer="phone"></span>
<span data-tiquo-customer="createdAt"></span>
<span data-tiquo-customer="firstActiveAt"></span>

The field path is read from the signed-in customer record. The Hosted Package can render these customer fields:

FieldDescription
idTiquo customer ID
firstNameCustomer first name
lastNameCustomer last name
displayNameCustomer display name
customerNumberOrganization customer number
emailPrimary email address
phonePrimary phone number
profilePhotoProfile photo URL
statusCustomer status, such as active, inactive, or banned
totalOrdersTotal number of orders
totalSpentTotal amount spent
createdAtRead-only Unix timestamp in milliseconds for when the customer profile was created
firstActiveAtRead-only Unix timestamp in milliseconds for the customer's first qualifying activity; absent until activity exists
emailsFull email array
emails.0.addressFirst email address
emails.0.isPrimaryWhether the first email address is primary
phonesFull phone array
phones.0.numberFirst phone number
phones.0.isPrimaryWhether the first phone number is primary
parametersFull customer parameter array
parameterValuesCustomer parameter values keyed by parameter ID and normalized parameter name

For image elements, use JavaScript to copy profilePhoto into src, or render it into an anchor/text element depending on your site builder's capabilities.

Created and First Active dates

createdAt and firstActiveAt have different meanings:

  • Created is when the customer profile was created. Customer activity never changes or backdates this value.
  • First Active is when the customer first became active through qualifying customer activity. It is not the database insertion time. Activities performed by staff, systems, integrations, or imports do not set it.

The values are equal when a customer creates their own account and is immediately active in the same flow. An imported or staff-created profile can have a later firstActiveAt, or no value until the customer becomes active.

Without formatting attributes, the Hosted Package renders the raw Unix millisecond value. Use data-tiquo-date-format to format a date declaratively:

<time
  data-tiquo-customer="createdAt"
  data-tiquo-date-format="datetime"
  data-tiquo-locale="en-GB"
  data-tiquo-time-zone="Europe/London"
></time>

<time
  data-tiquo-customer="firstActiveAt"
  data-tiquo-date-format="date"
></time>

Supported date formats:

ValueOutput
rawUnix timestamp in milliseconds
isoISO 8601 date and time
dateLocale-formatted date
datetimeLocale-formatted date and time

data-tiquo-locale is optional and defaults to the page language or browser locale. data-tiquo-time-zone is optional and accepts an IANA timezone such as Europe/London. When the customer changes, signs out, or does not have the selected value, the Hosted Package clears the element so stale customer dates are not displayed.

The imperative API always returns the raw millisecond values:

const session = await window.Tiquo.getUser();

console.log(session?.customer?.createdAt);
console.log(session?.customer?.firstActiveAt);

Render customer parameters

Customer parameters are custom fields configured in Tiquo. Render them with data-tiquo-customer-parameter.

<span data-tiquo-customer-parameter="Membership Type"></span>
<span data-tiquo-customer-parameter="membership_type"></span>
<span data-tiquo-customer-parameter="system_source"></span>

The value can be:

  • The parameter name, such as Membership Type
  • A normalized parameter key, such as membership_type
  • A system parameter ID, such as system_source
  • A custom parameter schema ID

Parameter names are normalized automatically, so Membership Type, membership type, and membership_type resolve to the same value.

Edit profile fields and customer parameters

Use data-tiquo-form="profile" to let a signed-in customer update their own profile.

<form data-tiquo-form="profile">
  <label>
    First name
    <input data-tiquo-profile="firstName" />
  </label>

  <label>
    Last name
    <input data-tiquo-profile="lastName" />
  </label>

  <label>
    Phone
    <input data-tiquo-profile="phone" />
  </label>

  <label>
    Membership type
    <select data-tiquo-profile-parameter="Membership Type">
      <option value="">Select one</option>
      <option value="Standard">Standard</option>
      <option value="VIP">VIP</option>
    </select>
  </label>

  <label>
    Interests
    <select data-tiquo-profile-parameter="Interests" multiple>
      <option value="Events">Events</option>
      <option value="Dining">Dining</option>
      <option value="Retail">Retail</option>
    </select>
  </label>

  <label>
    Marketing opt-in
    <input data-tiquo-profile-parameter="system_marketing_opt_in" type="checkbox" />
  </label>

  <p data-tiquo-message></p>
  <button type="submit">Save profile</button>
</form>

Editable built-in profile fields:

FieldDescription
firstNameCustomer first name
lastNameCustomer last name
emailPrimary email address
phonePrimary phone number
profilePhotoProfile photo URL

displayName is render-only. It cannot be edited through the Hosted Package or DOM Package. Tiquo derives it from first and last name. createdAt and firstActiveAt are also read-only system fields and are never included in profile update payloads.

Editable customer parameters use data-tiquo-profile-parameter. The value can be a parameter name, normalized key, system parameter ID, or custom parameter schema ID.

Dropdown and multiselect values are validated by Tiquo before saving:

  • select parameters can only save one configured, non-archived option.
  • multiselect parameters can only save configured, non-archived options.
  • Checkbox groups with the same data-tiquo-profile-parameter save as a multiselect array.
  • Single checkboxes save true or false, which works for boolean parameters.

If a form tries to save a value that is not available for that parameter, the save is rejected and the message element shows the error.

Render orders

<div data-tiquo-orders data-tiquo-limit="5">
  <div data-tiquo-order-item>
    <span data-tiquo-order="month"></span>
    <span data-tiquo-order="day"></span>
    <span data-tiquo-order="year"></span>
    <span data-tiquo-order="date"></span>
    <span data-tiquo-order="orderNumber"></span>
    <span data-tiquo-order="status"></span>
    <span data-tiquo-order="items"></span>
    <span data-tiquo-order="itemQuantity"></span>
    <span data-tiquo-order="total"></span>
  </div>

  <p data-tiquo-empty>No orders yet.</p>
</div>

Supported order fields include:

Attribute valueDescription
dateOrder creation date as DD/MM/YYYY
dayOrder creation day, such as 28
monthShort order creation month, such as JUN
yearOrder creation year, such as 2026
itemsComma-separated order item names
itemQuantityTotal quantity across all order items
itemQuantityLabelTotal quantity with label, such as 1 item or 2 items
totalOrder total formatted with the order currency and two decimal places, such as £12.50

Optional filters:

  • data-tiquo-limit="5"
  • data-tiquo-status="completed"

The first data-tiquo-order-item element is the template. Tiquo hides that template and appends rendered copies for each order.

data-tiquo-status filters by the order lifecycle status, not payment status. Use values such as completed, processing, cancelled, refunded, or open_tab. Do not use payment statuses such as paid here.

Render bookings

<div data-tiquo-bookings data-tiquo-limit="upcoming" data-tiquo-count="5">
  <div data-tiquo-booking-item>
    <span data-tiquo-booking="date"></span>
    <span data-tiquo-booking="day"></span>
    <span data-tiquo-booking="month"></span>
    <span data-tiquo-booking="year"></span>
    <span data-tiquo-booking="id"></span>
    <span data-tiquo-booking="serviceName"></span>
    <span data-tiquo-booking="items"></span>
    <span data-tiquo-booking="itemQuantity"></span>
    <span data-tiquo-booking="duration"></span>
    <span data-tiquo-booking="startTime"></span>
    <span data-tiquo-booking="endTime"></span>
    <span data-tiquo-booking="status"></span>
  </div>

  <p data-tiquo-empty>No upcoming bookings.</p>
</div>

Optional filters:

  • data-tiquo-limit="upcoming" or data-tiquo-limit="past"
  • data-tiquo-count="5"
  • data-tiquo-status="confirmed"

The first data-tiquo-booking-item element is the template. Tiquo hides that template and appends rendered copies for each booking.

data-tiquo-upcoming="true" still works for older pages, but new embeds should use data-tiquo-limit="upcoming" instead. When using upcoming or past, use data-tiquo-count for the number of bookings to render.

Booking fields:

FieldDescription
date or bookingDateBooking date formatted as DD/MM/YYYY
day or bookingDayTwo-digit booking day
month or bookingMonthThree-letter booking month, such as JUN
year or bookingYearFour-digit booking year
items or bookingItemsBooking service/item name. Falls back to the service record when no order snapshot exists.
itemQuantity or bookingItemQuantityBooking attendee/item quantity
itemQuantityLabel or bookingItemQuantityLabelQuantity with item or items label
id or bookingIdHuman booking number, such as BKG-1CTYN6
rawIdInternal booking row ID
duration or bookingDurationBooking duration, such as 30 min
startTime or bookingStartTimeBooking start time formatted as HH:mm
endTime or bookingEndTimeBooking end time formatted as HH:mm
statusBooking status
serviceNameBooking service name
serviceCategoryNameBooking service category name, when captured

JavaScript API

Use window.Tiquo.ready when you want to call the API after the script loads.

<script>
  window.Tiquo.ready(function (tiquo) {
    tiquo.track("booking_started", {
      eventName: "Booking Started",
      eventProperties: {
        source: "homepage"
      }
    });
  });
</script>

Available methods:

  • Tiquo.ready(callback)
  • Tiquo.track(eventType, options)
  • Tiquo.identify(options)
  • Tiquo.sendOTP(email)
  • Tiquo.verifyOTP(email, code)
  • Tiquo.getUser()
  • Tiquo.logout()
  • Tiquo.getOrders(options)
  • Tiquo.getBookings(options)
  • Tiquo.getUpcomingBookings(options)
  • Tiquo.render()
  • Tiquo.onAuthStateChange(callback)
  • Tiquo.setConsent(mode)
  • Tiquo.getConsent()

The Hosted Package does not expose raw access or refresh token getters.

En esta página