Confirming your payment

Paddle has your payment. This usually takes under a minute.

Help by DeltaBreen
PricingDocsConnect
Sign inStart free
← Docs

Your site's code: the support form and the Help button

On Shopify, Wix, Squarespace, Webflow or Framer, start with Site builders; built with AI, with AI app builders; in a mobile app, with Help in your app. This page is everything the script does, for your own code.

Two lines put the form on your page. You'll find them, with your key filled in, on your site's Install tab in the portal. It also has the same thing for React, Next.js and Vue.

<script src="https://help.deltabreen.eu/embed/v1.js" data-help-key="pk_live_…" async></script>
<db-help-form></db-help-form>

Want a working page to copy from? This one runs under a strict Content-Security-Policy: examples/customer-backend/server.mjs.

The script works wherever the tag ends up, including when a framework adds it for you (next/script, a head manager).

Keys

KeyForTickets
pk_test_…Trying things outMarked as test, don't count towards your plan, send no email, and are deleted a week after they were last touched
pk_live_…Your real siteReal

A live key only works on a domain you've verified (Settings → Domains, with a DNS record or a file on the site). Anywhere else we turn it away, the form says "This form isn't set up yet", and the browser console names the domain to verify. A test key works anywhere, localhost included.

A key is safe to show in a page. It only says which site a ticket is for. Who a visitor is can only come from your own server signing for them. Anyone your site didn't sign for is a guest, and is asked for their email.

Logged-in users

Tell the form who's logged in to your site. That person can then write in without typing their email, see their own tickets, and (on a plan with integrations) your agents see their account next to the ticket.

A page can't just say who its visitor is, or anyone could write in as anyone. So your server says it, by signing a short token with the site's secret. Create one on the site's Users tab. We show it once. The tab has this code for Node, Python and PHP.

// On your server, for the logged-in user. Never in the page.
import jwt from 'jsonwebtoken'

const token = jwt.sign(
  { sub: String(user.id), email: user.email },
  process.env.HELP_IDENTITY_SECRET,        // hsk_live_… with pk_live_…, hsk_test_… with pk_test_…
  { algorithm: 'HS256', expiresIn: '10m' },
)
Claim
subRequired. Your own id for the person, up to 128 characters. This is the id an integration gets.
expRequired. No more than 24 hours away. Ten minutes is plenty, because the form asks for a fresh token when it needs one.
emailOptional. We also send replies here.
jtiOptional. Any unique string. A token that has one works once.
userOptional. Up to ten short values your server vouches for about the person, like { "plan": "gold" }. See below.
header kidOptional. The secret's id (ik_…), if you want to say which secret signed it.

We only accept HS256. Any JWT library can do this. examples/customer-backend/server.mjs does it in six lines with no library at all.

What your server says about the user

Put short facts about the logged-in user in the user claim, and each ticket they send carries them:

jwt.sign({ sub: String(user.id), email: user.email, user: { plan: user.plan } }, secret, { algorithm: 'HS256', expiresIn: '10m' })

Your team sees them on the ticket under "From your site". On Business, a set of reply times can be for the customers whose plan is one of the values you choose (Settings, then Reply times), so they are answered sooner. Because your server signed it, a visitor can't claim a plan they don't have, and a guest has none.

A name is lowercase letters, digits and _, up to 40 characters. A value is a string, a number or true/false, up to 100 characters. Anything else in the claim is left out, and the user is still logged in. The values are as fresh as the token: stop signing plan and the user's next ticket has none. They are kept on the ticket, in that customer's export, and removed with the ticket. They are never sent back to the page.

Give the token to the form in one of two ways:

<!-- An address on your own site that returns the logged-in user's token, as text or as {"token": "…"},
     and 204 for a guest. We fetch it with your site's cookies, from your own origin only. -->
<script src="https://help.deltabreen.eu/embed/v1.js" data-help-key="pk_live_…" data-help-identity-url="/help-token" async></script>
DeltaHelp.identify(() => fetch('/help-token').then((r) => r.text()))   // or DeltaHelp.identify(token)
DeltaHelp.identify(null)                                                 // when they log out

Don't print the token into a page that a cache might serve to someone else. Fetch it instead.

In an app's web view, the app hands the token over before the page loads, as window.DeltaHelpIdentity, and the form opens as that user (Help in your app). An app with no website may instead hand over a key it keeps for the phone, as window.DeltaHelpDevice, where the site lets anyone with the app write in.

If we don't accept a token, the visitor is treated as a guest. They can still write in with their email if the site lets anyone send a message, and the browser console says exactly what was wrong with the token.

Getting a new secret. The old one keeps working for 24 hours, so put the new one on your server and nothing breaks. If someone else may have your secret, use Someone else has my secret. The old one stops straight away and everyone is logged out of the form.

What the script does

  • It loads from, and talks to, the host it was loaded from and nowhere else. It has no dependencies.
  • It sets no cookie and writes nothing to localStorage or any other storage. Its session lives in memory while the page is open.
  • It draws the form in a shadow root, so your CSS doesn't reach in and its CSS doesn't leak out.
  • Before a guest's message is sent, their browser does a short calculation (well under a second on a laptop). The form uses that in place of a CAPTCHA.
  • If you have published help articles, it sends what a visitor has typed so far, after each pause, to find the ones that match. We keep and log none of it. You can switch that off.
  • If the page's address ends in #help-ticket=…, from the button in one of our emails, it takes that out of the address at once and opens the ticket over the page (below).

Content-Security-Policy

If your site has one, this is all the form needs:

script-src  https://help.deltabreen.eu
connect-src https://help.deltabreen.eu

If you use data-help-identity-url, add 'self' to connect-src too, because that one request goes to your own site.

It needs no unsafe-inline, no unsafe-eval, no style-src entry, no frame and no worker.

Name our host, not one file on it. The script that reads help articles is a second file from the same host, loaded only when a visitor opens an article, and the one that shows a ticket opened from one of our emails is a third. If your policy names v1.js alone, those files are blocked: an article opens on your help page in a new tab instead, and a ticket on our page.

A picture in a help article is loaded from your own site. If it is on another of your hosts than the page showing it, that host needs to be in your img-src.

The element

<db-help-form subject label-button="Send" accent="#0a7d55"></db-help-form>
Attribute
subjectShow a subject field. Without it, the subject is the first line of the message.
accentThe colour of the button and focus ring, as six hex digits. Wins over the site's setting.
keyA key for this form only, for a page with forms for two sites.
field-…What your page already knows for one of the form's fields, by the field's key: field-order_id="A-100".
suggestsuggest="off" stops this form suggesting help articles while a visitor writes.
label-…Any of the form's words: label-title, label-intro, label-email, label-email-hint, label-subject, label-body, label-choose, label-attach, label-remove-file, label-file-too-big, label-file-kind, label-file-too-many, label-sending-files, label-file-failed, label-button, label-success, label-reference, label-another, label-sign-in, label-articles-title, label-article-back, label-article-solved, label-article-thanks, label-article-write, and when something can't be sent label-unreachable, label-too-many, label-misconfigured, label-bad-email, label-empty-message, label-too-long, label-field-required, label-field-tick, label-bad-field ({field} is the field's name), label-form-paused, label-send-again and label-refused for anything else. Use these to translate the form: what our server says is in English and goes only to the console.

Words you set here win over the site's Form tab in the portal, which wins over the defaults.

Languages

The form speaks the language of the page it's on: the lang of the element or of something around it, usually your <html lang="de">. We have our own words in English, German, French, Spanish, Italian and Dutch. A page in any other language, or one that says none, gets the language you chose for the site on its Form tab. A visitor's browser setting is never used, so an English page stays English for a visitor whose browser is set to German.

In that language, the form shows the words you wrote for it on the Form tab (under "Other languages"), then your site's own words where you wrote none for it, then ours. A label-… attribute still wins over all of them, so a page in two languages can give each its own words.

The ticket remembers the language its form was shown in. The emails about it and the page its link opens are in that language too.

Events, on the element (they bubble):

Eventdetail
help:sent{ number }
help:error{ code }
help:article{ slug }: a help article was opened
help:answered{ slug }: "That answered it" was pressed

Styling from outside: the custom properties --dbh-accent, --dbh-on-accent, --dbh-radius, --dbh-gap, --dbh-line, --dbh-danger on the element, and these parts:

  • The form: form, title, intro, field, input, checkbox, attach, file-input, files, file, button, message, confirm-hint, away, reference, badge, test-mode, and for help articles articles, article-link, article, article-title, article-body, section.
  • A user's own tickets (<db-help-tickets>): the list's tickets, title and list; each row's ticket (with ticket-unread while it has a reply they haven't read), ticket-subject, ticket-date, ticket-status and ticket-preview; a conversation's back, ticket-title, ticket-state, ticket-number, ticket-status, thread, update, and each message's message-mine or message-support, message-who, message-author, message-time, message-text, files and file; the rating's rating, rating-title, stars, star; and the reply box's reply, field, field-label, reply-input, reply-button, attach, away, error.
  • A ticket opened from an email on your help page (<db-help-ticket>, below): the same names for the same pieces, and conversation, confirm, emails and keep-link for what only it has.
  • The launcher: launcher, unread, panel, tab, close.
db-help-form { --dbh-radius: 2px; }
db-help-form::part(button) { text-transform: uppercase; }
db-help-tickets::part(ticket-preview) { font-style: italic; }

Text and borders use your page's own text colour, so the form fits a light or a dark page as it is.

Fields

A form can ask for more than the message. On your site's Form tab in the portal, under Fields, add what you want to know. The form on your site asks for it straight away, in the order of the list, and your team sees the answers on the ticket and can filter tickets by them.

TypeThe visitor sees
Short textA one-line box, up to 200 characters.
NumberA box for a number.
DateA date picker.
DropdownA list of your options.
CheckboxA box to tick.
Filled in by your pageNothing. Your page gives the value.

Severity and category are two ready-made dropdowns on every plan. What a visitor picks for severity is the priority the ticket starts with (low, normal, high or urgent), and your team can change it. Fields of your own are on Lite and higher (3 a site on Lite, 10 on Pro, any number on Business). A field can be required. On Pro and higher it can be shown only for some answers to a dropdown or a checkbox above it. A field that is not shown is not asked.

Each field has a key, shown where you edit it. Use the key to give the form a value your page already knows, for a field your visitor shouldn't have to type or a field they never see:

<db-help-form field-order_id="A-100"></db-help-form>
DeltaHelp.setFields({ order_id: 'A-100', cart_total: 59.9 })   // for every form on the page

A value from your page is sent by the visitor's browser, like everything else in the form. Your team sees it marked "From the page". Don't rely on it to say who someone is: that is what a logged-in user is for. A key the form doesn't have is ignored.

Files (Lite and higher)

Where your plan has attachments, the form shows Attach files, and so do a user's own tickets and the page our emails link to. A visitor can also paste a screenshot into the message. Your team attaches files to a reply the same way.

  • Up to 5 files a message, 10 MB each: pictures (PNG, JPG, GIF, WebP), PDF, plain text (.txt, .log, .csv, .json, .md) and ZIP. We look at what a file is, not at what it is called, and take nothing else.
  • A file is sent after its message, to our API and nowhere else, so the Content-Security-Policy below is all a page needs. If a file can't be taken, the message is still sent and the form says which file was left out.
  • Nobody gets a file from your site or from ours. Pressing a file's name asks us for a link that works for one minute and downloads the file from our file store.
  • A file is deleted with its ticket. Each plan has an amount of file storage; when it is full, new files are refused until tickets are deleted or you move to a bigger plan. Nothing is billed.

Without the form, send the files yourself once the message is taken:

const sent = await DeltaHelp.submit({ email, body })
if (sent.upload) for (const file of input.files) await DeltaHelp.upload(sent.upload, file)

Your own form (Lite and higher)

On your site's Form tab in the portal, choose Your own HTML & CSS. You get an editor with a live preview. Write the form's HTML and CSS, and the form on your site changes the moment you publish. You don't touch your pages. A draft isn't live until you publish it, and you can go back to the simple form any time.

Mark the parts the form needs with data-help:

HookOn
body<textarea>Required. The message.
submit<button>Required. Sends it.
email<input>Required if anyone can send a message. Hidden for a logged-in user.
subject<input>Optional.
erroranyOptional. Where a problem is shown (too many messages, an email we can't reply to).
successanyOptional. Shown in place of the fields once the message is sent.
numberanyOptional, inside success. We fill in the ticket's number.
filesanyOptional. Where the Attach files button goes. Without it, it goes above the send button.
articlesanyOptional. Where suggested help articles go. Without it, they go above the send button.
<h2>Talk to us</h2>
<label>Email <input type="email" data-help="email" required></label>
<label>Message <textarea data-help="body" rows="5"></textarea></label>
<p data-help="error" hidden></p>
<button type="submit" data-help="submit">Send</button>
<p data-help="success" hidden>Thanks. Your reference is #<span data-help="number"></span>.</p>

Place one of the form's fields with data-help-field and the field's key: on a <select> for a dropdown, on an <input> for the others. We fill a dropdown with the field's options, so leave it empty. A field you don't place is added above the button, so your form always asks what the Form tab says it asks.

<label>Topic <select data-help-field="category"></select></label>
<label>Order number <input data-help-field="order_id"></label>

Leave a place for one of the form's words with data-help-text and its name, and we fill it in the language the form is shown in, so one form serves every language: title, intro, email, emailHint, subject, body, attach, button, signIn or articlesTitle. What you write inside the element is replaced.

<h2 data-help-text="title"></h2>
<button type="submit" data-help="submit" data-help-text="button"></button>

Your form can have layout, text and form fields: div, span, p, h1–h4, lists, strong, em, small, br, hr, a, label, input, textarea, select, option, button, fieldset, legend, with class, id, hidden, role, title, lang, dir, data-help-text and aria-…. An input can be a text, email, tel, url, number, date or checkbox field. Links must be https: or mailto:. We take everything else out when you save, and the editor tells you what went: scripts, frames, images, inline style, handlers such as onclick, a form's action. The form runs on your customers' pages, so nothing in it can run code, whoever typed it.

Your CSS only applies inside the form. Your page's styles don't reach in, and the form's don't reach out. :host is the element itself. Your CSS can't use @import or a backslash, and an address in url(…) must be https:// or it becomes none. If your page has a Content-Security-Policy, an image you point at needs its host in your img-src.

Each can be up to 20 kB. docs/template-allowlist.json is the exact list.

Help articles (Pro and higher)

Write articles on your site's Articles tab in the portal. Nothing shows on your site until you publish one, and a change to a published article waits until you publish it again.

In the form. While a visitor writes, the form shows up to three articles that match, under the message. Pressing one opens it in place of the form. Their message, and any files, are still there when they go back, and they can always send it. To find the articles, the form sends us what the visitor has typed so far, about half a second after they stop typing. We search with it and keep none of it: not in a database, not in a log. If you would rather it didn't, switch off Suggest articles in the form on the Articles tab, or put suggest="off" on one form.

An article is suggested when the visitor types one of its words customers use, two words of its title, or several words of its text. Try a search on the Articles tab shows what a message would bring up.

On your help page.

<db-help-articles></db-help-articles>

This lists your published articles by section, with a search box, and opens one in place. The search box finds an article by any word in it; what is typed there is sent to us to search with and, like the form's, kept nowhere. It shows nothing until you have published an article. The article being read is in the page's address (https://your-site.com/help#help-article=how-do-i-get-a-refund), so a link to it can be sent, and the browser's Back button goes to the list. Give the page's address as Help page address on the Articles tab and your team can put an article's link into a reply from the ticket.

Attribute
sectionShow only the articles in one section: section="Billing".
inlineKeep the article being read out of the page's address, for a list inside something that opens and closes. The launcher's own list has it.
contactWhere "Still need help? Write to us" under an article leads: a path on your site (/contact) or a place on the page (#form). With a <db-help-launcher> on the page it opens that, and this isn't needed.
key, accent, label-…As on the form. Its words: label-articles-search, label-articles-back, label-articles-none, label-articles-contact, label-article-solved, label-article-thanks.

Writing one. An article is a small Markdown, drawn on your page as text and never as markup:

You writeYou get
## Heading, ### Smaller headingA heading
- item, 1. stepA list
**bold**Bold words
A word between two backticksSomething to type or copy
three backticks on a line of their own, above and belowA block shown exactly as typed
[words](https://…), [words](mailto:…)A link, opened in a new tab
[words](#help-article=the-other-articles-link)A link to another article, opened in place
![what it shows](https://your-site.com/img/orders.png), on a line of its ownA picture

A picture must be on one of the site's verified domains, by https. We don't store pictures and an article can't load anything from anywhere else, so nothing on your page calls a host you didn't put there.

What we count. Each time an article is opened on your site, and each time "That answered it" is pressed, we add one to that article's number for the day. The Articles tab shows the last 30 days. Nothing about the visitor is kept with it, and a page using your test key counts nothing.

A user's own tickets

<db-help-tickets></db-help-tickets>

For a logged-in user, this shows their own tickets, each with your team's replies, and a box to reply. It only shows what was said to them. Private notes and your team's email addresses never appear. A guest sees "Log in to see your tickets" (they get their replies by email instead).

Your own layout (Lite and higher)

On your site's Ticket pages tab in the portal, choose Your own HTML & CSS to write the list and the conversation yourself, with a live preview. Your layout is used for a logged-in user's tickets on your site and for a ticket opened from one of our emails, on your help page and on ours. A draft isn't live until you publish it, and you can go back to the built-in pages any time.

A layout has two parts side by side: list, with a row we repeat for each ticket, and ticket, the conversation, with a mine and a theirs we repeat for each message. We put each ticket's words in the places you mark, as text.

HookInside
listRequired. The list of tickets.
emptylistShown when there are none.
rowlistRequired. One ticket. A <button> in it opens the ticket, or the whole row does. A row with a reply they haven't read has the class unread.
subjectrow or ticketThe ticket's subject. Required in a row.
status, numberrow or ticketWhere it stands, and its number.
date, previewrowWhen the latest message was sent, and how it starts.
unreadrowShown only while a reply hasn't been read.
ticketRequired. One ticket's conversation.
backticketA <button> back to the list. Without it we add one. A ticket opened from an email has none.
messagesticketRequired. Where the messages go.
mine, theirsmessagesRequired. One of the customer's messages, and one of your team's replies.
who, when, text, filesmine and theirsWho wrote it, when, what (required), and the files sent with it.
updatemessagesA line saying who has the ticket. Without it, we use the tag of theirs.
ratingticketWhere the stars go once it's closed. Without it, under the messages.
replyticketRequired, on a <textarea>.
attach, error, awayticketWhere the button for files goes, where a problem is shown, and your away message after a reply. Without them, above the send button.
sendticketRequired, on a <button>.
<div data-help="list">
  <h2 data-help-text="ticketsTitle"></h2>
  <ul>
    <li data-help="row"><button><strong data-help="subject"></strong> <span data-help="status"></span></button></li>
  </ul>
</div>
<div data-help="ticket">
  <button data-help="back" data-help-text="back"></button>
  <h2 data-help="subject"></h2>
  <ol data-help="messages">
    <li class="me" data-help="mine"><span data-help="text"></span></li>
    <li class="you" data-help="theirs"><b data-help="who"></b> <span data-help="text"></span></li>
  </ol>
  <textarea data-help="reply"></textarea>
  <button data-help="send" data-help-text="replyButton"></button>
</div>

data-help-text leaves a place for one of our words, said in the page's language: ticketsTitle, ticketsEmpty, back, reply, replyButton or attach. A layout may use the same tags and attributes as your own form, and its CSS works the same way: it applies only inside the layout, and nothing of ours does, so the stars (.stars, .star, .star.on) and the file button we put in your places take your styles, and the parts above don't reach in. On a page that can't build it, such as one that enforces Trusted Types, the built-in pages are shown.

The launcher

<db-help-launcher></db-help-launcher>

A button in the corner of the page. It opens the form and, for a logged-in user, their tickets, and it shows how many replies they haven't read. Once you have published help articles, it has a Help articles tab too, with the same list and search as <db-help-articles>; an article read there stays in the panel and leaves the page's address alone. position="left" moves it to the left. Its words and colour come from the site's settings. Use it as well as, or in place of, the other two elements.

All the elements take the same key, accent and label-… attributes. More words for these two: label-tickets-title, label-tickets-empty, label-tickets-sign-in, label-status-open, label-status-progress, label-status-pending, label-status-closed, label-assigned, label-assigned-someone, label-closed-quiet, label-back, label-reply, label-reply-button, label-you, label-support, label-rate-title, label-rate-stars, label-rate-words, label-rate-button, label-rate-thanks, label-launcher, label-close, label-tab-new, label-tab-mine, label-tab-help, and for a rating that can't be given label-cannot-rate, label-not-closed and label-bad-rating.

More events: help:unread with { unread } whenever the number changes, help:replied with { number }, and help:rated with { number, stars }.

When you ask for ratings (Settings, then Rules, on Pro and higher), a closed ticket in <db-help-tickets> asks "How did we do?": five stars and an optional line. Nothing is sent until the user presses the button. They can change their answer while the ticket stays closed, and a reply from them opens it again. DeltaHelp.unread() gives the number to a site that shows it in its own menu.

Without the form

window.addEventListener('deltahelp:ready', () => {
  DeltaHelp.setContext({ plan: 'pro', cart_items: 3 })   // shown to the agent as not verified
})

const { number } = await DeltaHelp.submit({ email, body, subject, fields: { category: 'billing', order_id: 'A-100' } })

fields holds the answers to the form's fields, by key: text for a short text, a number or a date (2026-10-12), an option's value for a dropdown, true or false for a checkbox.

If it fails, DeltaHelp.submit rejects with a DeltaHelp.HelpError. It has a code, a message, a status and, when we said how long to wait, retryAfter in seconds.

codeMeaning
bad_email, empty_message, message_too_long, subject_too_longWhat was typed
field_required, bad_fieldA field of the form was left empty, or holds something it can't. message names the field
sign_in_requiredOnly logged-in users can write to this site
rate_limitedToo many messages from this address or to this site. See retryAfter
form_pausedThe form isn't taking messages right now
bad_keyWe don't know the key, or it was replaced
origin_not_verifiedA live key on a page whose domain isn't verified for the site
bad_identityWe didn't accept the identity token. message says why
unreachableThe request didn't reach us (offline, or blocked on the way)

Email

If we have an email for someone (they typed it, or their identity token had one), they get your replies by email as well as on the ticket. It goes in this order:

  1. One fixed email asking them to confirm their address, the first time they write to a site. It names your site by its domain and gives the ticket's reference. Nothing anyone typed is in it.
  2. Once they open its link and press Confirm, each reply your team sends, as plain text, with a link to the whole conversation.

The link opens the ticket on your help page, where they can read the conversation and reply (below); with none, it opens on a page of ours. They can also simply reply to the email: what they write above the email they quote joins the ticket, and if they confirm their address that way it counts as pressing Confirm. A reply from someone else, such as a colleague they forwarded it to, reaches your team as a private note naming who sent it. They can turn the emails off from that page any time. We ask an address to confirm at most once a day, each plan has a number of emails a day, and a test key sends none.

Under each reply, your team can see whether it was also emailed, and if not, why.

The form's words after sending are label-success, and label-confirm-hint when we sent a confirmation email. When your team is away (Settings, then Rules, on Pro and higher), the away message you wrote is shown after them as text, in part="away"; submit() and reply() answer it as away when you draw the form yourself.

Your support mail as tickets (Lite and higher)

Your site gets a forwarding address of its own (in the portal: Sites, then your site, then Settings). Forward your support address to it, and each email becomes a ticket from that person, as a guest by their address, with any files kept as your plan allows. A reply that names one of your tickets by its number (#119, as our emails' subjects do), from that ticket's customer, joins it instead. Auto-replies and bounces are never answered, and newsletters go to Spam.

  • Microsoft 365: an admin allows forwarding outside your company first (Microsoft Defender, Anti-spam, Outbound policy, Automatic forwarding: On), then sets forwarding on the support mailbox, or adds a mail flow rule that redirects its mail to the forwarding address.
  • Google Workspace or Gmail: Settings, Forwarding and POP/IMAP, Add a forwarding address. Google emails a code to the forwarding address; it arrives as a ticket, where you can read it.
  • If the address ever leaks, get a new one there: the old one stops taking mail at once.

Opening a ticket from an email

Give your site a help page (in the portal: Sites, then your site, then Settings), a page of your own with the script on it. The button in each of our emails to your customers then opens their ticket there, so they never leave your site: the script finds #help-ticket=… at the end of the address, takes it out at once, and shows the ticket over the page, in your colour and in the language its form was shown in. They read and reply there, confirm their address, and rate how it went. The ticket is drawn in a <db-help-ticket> element, which your CSS styles from outside with the parts above (db-help-ticket::part(message-support) { … }), or in your own layout: then our line saying who the conversation is with stays above it, and the email settings below it.

  • We look for the script with your site's live key on that page when you save it, and again each day. If it's gone, the buttons open tickets on our page until it's back, and we email you once it has been missing a day.
  • A WordPress site with our plugin needs nothing set: with no help page, the buttons open tickets on its home page.
  • The part after #help-ticket= opens that ticket for whoever has it. Our script takes it out of the address as soon as it loads, but a script of yours that runs first, such as analytics, chat or session recording, can still read the address. Keep those off your help page if you'd rather they never see it.

What is sent with a ticket

The message, the subject, the email (guests only), the answers to the form's fields, any files, the page's URL, the browser's language, anything you passed to setContext, and what our server sees of the request: the page's origin and the browser's user-agent string. We don't store an IP address with a ticket.

Help by DeltaBreen

A helpdesk that lives inside your own site. One price per workspace, never per agent.

Get started

PricingDocsConnect

Legal

TermsRefund policyPrivacyData processing agreementSecurity

Company

[email protected]© 2026 DeltaBreen Limited · Company number 826627 · Gorey, Co. Wexford, Ireland