Setup guide
About 10 minutes, start to finish. Your dashboard fills in your own campaign code in every snippet below, so you can copy from there.
1. Create a campaign
Open the dashboard and press New campaign. Choose:
- Each person gets their own deadline (evergreen), and how long it lasts, or one date for everyone (a launch).
- Then end at a set time of day (optional): for example 72 hours, then 11:59 PM in New York. The deadline is never shorter than the length you set.
- When the deadline starts: Only from my email tool (the safest: only your email tool can start a deadline, see section 5), or on the first email open, page visit or webhook, whichever comes first (the default, and the only choice on Kit's free plan).
- Language: the timer's labels, the end date and the "Limited-time offer" notice in 14 languages. Picking one fills in its words; change them as you like.
- People with no deadline: someone who opens your offer page without coming from your emails, or whose link is broken. Show them the page as normal, or send them to another page, like your sign-up page.
- After the deadline, send visitors to: the page people see once the offer is over, for example your full-price sales page.
- Look: boxes or a clean style, your colour, the words above the timer, the words when it's over, and the four labels (DAYS, HOURS... in your own language if you like; accented letters work).
2. Put the script on your offer pages
Paste this in the <head> of your sales page and checkout page (in WordPress, use the plugin instead):
<style>html:not(.evd-ready) [data-evd-when=expired],html:not(.evd-ready) [data-evd-when=none]{display:none!important}</style>
<script src="https://tofulabs.app/deadlines/t.js?v=637c1d61b7" data-campaign="YOUR_CAMPAIGN_ID"></script>
The first line keeps your "ended" and "no deadline" sections (below) hidden until our script has checked the visitor, so if the script can't load (a privacy extension, an outage), people see only your offer.
Then put a timer where you want one:
<div data-evd-timer></div>
That draws the same timer as your email: the words above it, then days, hours, minutes and seconds in your campaign's look. For one line of text instead, use <span data-evd-timer data-evd-style="inline"></span>. To leave the words above the timer out on one timer, add data-evd-heading="off" (or untick it in the campaign's settings for every page).
Optional extras
- A bar across the top of the page: add
data-bar="top"(or"bottom") to the script tag. - Show the exact end time:
<span data-evd-date></span>prints it word for word as your emails do, in the campaign's time zone and language with the zone's short name, like "Friday, October 9 at 11:59 PM EDT". A subscriber comparing the email and the page sees the same day and time. - Different content before and after: wrap blocks in
<div data-evd-when="active">,<div data-evd-when="expired">or<div data-evd-when="none">(for visitors with no deadline). - Keep visitors on the page after the deadline instead of redirecting them: add
data-redirect="off"to the script tag and use the sections above.
Check your page before you send
Open your offer page with ?evd_preview=1 at the end of its address (for example https://yoursite.com/offer?evd_preview=1). You'll see the timer at its full length with a small "Preview" label. It never redirects you, saves nothing and doesn't count toward your plan, so you can check the page as often as you like. Links to your checkout carry the preview along.
3. Link from your emails with the subscriber's email
Add evd_email= and your email tool's merge tag to every link that goes to the offer. The script reads it, then removes it from the address bar. If the script can't load at all (for example a browser extension blocks it), the address stays as it was; the WordPress plugin removes it in that case too.
https://yoursite.com/offer?evd_email={{ subscriber.email_address }}
Use your tool's own tag for the email address:
| Email tool | Merge tag |
|---|---|
| Kit (ConvertKit) | {{ subscriber.email_address }} |
| Mailchimp | *|EMAIL|* |
| ActiveCampaign | %EMAIL% |
| MailerLite | {$email} |
| Brevo | {{ contact.EMAIL }} |
| Klaviyo | {{ email }} |
<head>, and in Google Analytics turn on Data redaction for email addresses (Admin → Data streams → your stream → Redact data), which new streams have on already.4. Add the countdown image to your emails
Insert an image (or an HTML block) with this address, using the same merge tag:
<img src="https://tofulabs.app/deadlines/e/YOUR_CAMPAIGN_ID/{{ subscriber.email_address }}.gif" width="480" alt="Time left on your offer">
The image shows days, hours, minutes and seconds left and ticks down for a minute while the email is open. Once the deadline has passed it shows your "it's over" words. It's worked out fresh each time the email is opened, so an email opened late shows the right time. Outlook on Windows doesn't play animations: it shows the first frame, which is still the right time.
In your email editor, where the merge tag isn't filled in yet, the image shows a sample timer labelled "Preview: each subscriber sees their own time left". Each real subscriber sees their own.
5. Start deadlines from your email tool (optional)
Every campaign has a private webhook address (in the dashboard under Set it up). When your email tool sends it a subscriber, their deadline starts right then, before they open anything. Sending the same person again changes nothing.
Kit
- In Kit, open Apps, find Send a Webhook (Kit's own app) and click Install.
- Open Automations → Visual automations and edit the automation people enter when they should get the offer (for example one that starts with Tag is added or Joins a form).
- Click the + where the deadline should start, choose Action, then Send a Webhook → Webhook.
- Paste your campaign's webhook address into Webhook URL, give it a Webhook Name such as "Start deadline", and click Add Action. Put it before the email that shows the countdown.
Kit's Send a Webhook app and its Webhooks page (Automate → Webhooks, for events like "Tag is added") need a paid Kit plan. On Kit's free plan, let the deadline start on the first email open or click instead: that needs no setup at all.
Kit runs automation steps in batches, so the first webhook call can arrive a few minutes after someone enters the automation. To see it arrive, open the campaign's Set it up tab: Recent webhook calls lists the last 30 calls, who they were for and what happened (a deadline started, one already running, or the reason it was refused).
ActiveCampaign
Edit your automation, click + where the deadline should start, and in Add an action choose Workflow → Webhook. Paste the address and save. Webhook actions are on ActiveCampaign's Plus plan and up.
Mailchimp
Click Audience, then More options → Audience settings → Manage webhooks → Create webhook. Paste the address as the Callback URL, tick only Email subscribes, and click Create webhook. Every new subscriber gets a deadline right away.
MailerLite
In your automation, click + where the deadline should start and choose Webhook. Paste the address as the Webhook URL. MailerLite also asks for its Secret Key (from its Integrations page); we don't need it.
Zapier, Make and everything else
Send the subscriber's email to the address as JSON, a form or ?email=: a "Webhooks by Zapier → POST" step or a Make "HTTP → Make a request" step with a field called email. The response tells you the deadline: {"ok":true,"ends":1760112000000,...}.
Every call, from any tool, shows up under Recent webhook calls on the campaign's Set it up tab, with what came of it.
Set the end time yourself
Add ends= (or deadline=) to give a new person a set end instead of the campaign length, for example when you move people over from another tool: [email protected]&ends=2026-11-02T18:00. It takes ISO dates like 2026-11-02T18:00:00Z, 2026-11-02 18:00, 11/02/2026 6:00 PM (month first), a date alone (11:59 PM that day) or Unix time. Times without a zone use the campaign's time zone. A person who already has a deadline keeps it; one that has already ended is saved as ended and doesn't count toward your plan.
6. Put the date in your Kit emails (optional)
In the dashboard, open Account and paste a Kit v4 API key (in Kit: Settings → Developer → API keys → Add a new key). We keep it encrypted. From then on, when someone's deadline starts, we write two custom fields on their Kit subscriber:
deadline_text: the end in words, in the campaign's time zone and language, with the zone's everyday name: "Friday, October 9 at 4:28 PM EDT" for New York, "Saturday, October 10 at 5:28 AM JST" for Tokyo. In an email:{{ subscriber.deadline_text }}.deadline_at: the same moment as a date and time (ISO 8601, UTC), for automations and conditions.
Each campaign can use its own field names (in its settings: "spring" gives spring_text and spring_at), so two offers never overwrite each other. We create the fields in Kit for you. Give someone more time in the dashboard and their fields update too. When someone has only just joined, Kit can take a little while to finish saving them, so if Kit doesn't know them yet we try again: after 20 seconds, then over the next 3 hours (the Account page shows how many are waiting). If Kit refuses a write for good (a deleted key, someone who never becomes a Kit subscriber), the Account page lists it under Recent problems with their email address; they stay there until you clear them.
{{ subscriber.deadline_text | default: "soon" }}. The countdown image needs neither: it's worked out when the email is opened.7. Count sales (optional)
Put this on your thank-you page, after checkout:
<script src="https://tofulabs.app/deadlines/t.js?v=637c1d61b7" data-campaign="YOUR_CAMPAIGN_ID" data-sale data-amount="79" data-currency="USD"></script>
It counts one sale for the buyer (a reloaded thank-you page doesn't count twice), and never starts or changes a deadline. The amount and currency are optional; write the amount as a plain number like 49.00. It finds the buyer the same way as your offer pages: the deadline saved in their browser, a link with evd_t or evd_email, or ?email= if your checkout passes the buyer's email to the thank-you page. If the thank-you page is on your checkout's own domain, list the checkout in the campaign's "Other pages" so the visitor's deadline travels there.
Each campaign's Results tab shows new people per day for the last 30 days, sales, and the share of buyers who bought before their deadline.
8. People
The People tab lists the latest people (running, ended or bought) with their email address, and Export CSV downloads everyone: email, start, end, how it started, visits and what they bought. Click someone to help them: Give more time sets a new end for that one person, and Remove deletes their deadline so they start fresh the next time they arrive. If they bought, the sale stays in your Results (the Bought filter still lists it), but their email address is erased, so Remove also answers a request to delete someone's data. Nothing ever resets by itself.
People who started before 9 October 2026 show a short form of their email, like t•••[email protected], until they next open an email or visit your page. Visitors with no email show as "Device only".
Switching from Deadline Funnel
Bring your people over with the deadline they already have, so nobody mid-sequence gets a brand-new window.
- In Deadline Funnel, open your campaign, click Open Analytics, set the date range so it covers everyone who joined (the export only has people from the range shown), and click Export.
- Here, make a campaign with the same length, open its People tab and press Import CSV. Pick the file, check that the email and deadline columns are the right ones, and press Check the file. If the dates are written like 03/04/2026, we ask whether that's March 4 or 3 April (we work it out when a date like 13/04 settles it).
- You'll see how many people will be added, how many already have a deadline here (they keep theirs), each row we can't use and why (an impossible date like 31 April is refused, never moved to another day), and a few dates as we read them. Press Import.
- Swap the Deadline Funnel script and email images for ours (sections 2 to 4). Do it on the day you import, so both tools agree.
Writing a file yourself? Use the template in the import box: one email column and one end time written year first, like 2026-11-20 18:00 (ISO 8601), which can't be misread. Times without a time zone are read in the campaign's zone. People whose deadline is still running count toward this month's new deadlines; ones that already ended are free. Imported people aren't written to Kit's fields; if you use those, run the import, then send each person through your Kit webhook step with ends= (section 5) instead. You can also skip the file entirely and use ends= from Zapier or Make.
9. WordPress
Install the free Evergreen Deadline plugin and paste your workspace key in Settings → Evergreen Deadline. Then pick a campaign in the "Deadline Countdown" block, or in the Evergreen Deadline panel of the page editor's sidebar (Page tab), where you also set the redirect, the bar and "This is a thank-you page". To show content only while someone's deadline runs, after it ends, or to people with no deadline, use the Deadline content block or the shortcodes on the plugin page. The plugin also has fixed-date timers that work without an account.
Your account
- Your workspace opens with its key. Add a recovery email in Account and you can also sign in with a link we email you (it works once, for 15 minutes). We also email you when you've used 80% and 100% of your plan's new deadlines for the month.
- If your key may have leaked, make a new one in Account. The old key stops working at once; paste the new one in the WordPress plugin if you use it.
Good to know
- Deadlines never restart by themselves. Changing the campaign length only affects people who start after the change.
- Over your plan's monthly limit, people who already have a deadline keep it. New people get an email image that says "Limited-time offer" and your pages show without a countdown, until next month or until you upgrade.
- If our service can't be reached, your page shows normally without a timer, so a problem on our side never blocks your sales. Your "active" sections show and the "ended" and "no deadline" ones stay hidden (with the style line from step 2, which the WordPress plugin adds for you).
- Visitors whose browser blocks our script (some privacy extensions do) see your page without a timer and are never redirected, even after their deadline. That's true of any script-based timer; a checkout that closes on the server is the only way to be certain, and with the style line they still never see contradictory sections.
- Questions? Email [email protected]. We read every email and aim to reply within two business days.