Dashboard

The dashboard at https://timetriggers.io/dashboard is where you create API keys and follow your triggers. The API schedules, edits and cancels triggers but doesn't report back on them: a trigger's status, its attempts and your target's responses are only visible here.

PageAddressWhat it's for
API Keys/dashboardCreate, copy and delete API keys.
Triggers/dashboard/triggersBrowse and search your triggers, cancel and replay them. Updates live.
Executions/dashboard/executionsEvery attempt across your triggers, with filters such as Only dead letters.
Tag Policies/dashboard/tag-policiesAdd, edit and delete tag policies.

The → link on a row of Triggers or Executions opens the trigger page, /dashboard/triggers/<trigger-id>.

Signing in

There are no passwords. You sign in with a one-time code sent by email:

  1. Go to the sign-in page and enter your email address. Opening the dashboard while signed out takes you there too.
  2. Click Send code. The code comes from noreply@timetriggers.io, with the subject "Your TimeTriggers verification code: …".
  3. Enter the 6-digit code and click Verify & sign in. You land on the API Keys page.

Your first sign-in creates your account. There's no separate sign-up, and no way to sign in with a password.

About codes:

  • A code is valid for 5 minutes and works once.
  • Only the newest code works. Requesting a new code invalidates the previous one. Entering the old one then fails, and counts as a wrong attempt against the new code.
  • There's no resend button. To get a new code, click ← Use a different email, then Send code again.
  • 3 wrong attempts lock a code. It then fails even if you enter it correctly. Request a new one.
MessageWhat to do
Invalid OTPThe code is wrong, has been replaced by a newer one or was already used. Check the code or request a new one.
OTP expiredThe code is older than 5 minutes. Request a new one.
Too many attemptsThe code was locked after 3 wrong attempts. Request a new one.
Too many requests. Please try again later.More than 3 code requests, or more than 3 sign-in attempts, from your IP address within a minute. Wait a minute.

A session lasts 7 days. Using the dashboard extends it (at most once a day), so you're signed out only after about a week without a visit. Sign out, at the top right, ends the session right away.

Your project

The first time you open the dashboard, a project is created for your account automatically. API keys, triggers, tag policies and the monthly quota belong to the project, not to you or to an API key.

  • New projects are on the Free plan, with 500 /schedule calls per month. The dashboard doesn't show the project's name, plan or remaining quota; see Checking your remaining quota.
  • You can't invite teammates, rename the project or switch projects from the dashboard.
  • If your account is a member of more than one project, Triggers and Executions show the triggers of all of them together, without saying which project each belongs to. API Keys and Tag Policies manage only one of the projects.

API keys

The API Keys page lists your project's keys, newest first, with their name, the start of the key and the date it was created.

To create a key:

  1. Click Create key.
  2. Optionally, enter a Key name such as Production or Staging. Without one, the key is named Default. Names don't have to be unique.
  3. Click Create.
  4. Click Copy next to the key to copy it in full.

A key looks like ttr_ followed by 48 hex characters. Send it in the ttr-api-keyheader header; see Authentication.

Good to know

  • Keys can be copied at any time. The list shows only the first 12 characters, but Copy copies the whole key whenever you click it, not only right after creation. Anyone who can sign in to your project can copy every key, so protect dashboard access like the keys themselves.
  • Every key has full access to the project. Keys have no scopes. Any key can edit or cancel triggers created with another key.
  • Keys never expire. A key works until you delete it. Keys can't be renamed.
  • Keys are managed only in the dashboard. The endpoints behind this page accept a dashboard session, not an API key.

Deleting a key

Delete removes the key immediately, without confirmation and with no undo. From the next request on, every call that uses that key, in ttr-api-keyheader or in Authorization: Bearer where that's accepted, gets 401 with the message Invalid api key.

Deleting a key doesn't cancel anything. Triggers belong to the project, not to the key that created them. One-shot triggers scheduled with a deleted key still fire, and its recurring triggers keep creating and firing instances. You can't cancel them with the deleted key: use another key of the project, or the dashboard.

Rotating a key

To replace a key, for example after it leaked:

  1. Create a new key and switch your clients to it.
  2. Delete the old key.
  3. Go through your triggers (a recurring trigger shows up as its upcoming instance) and your tag policies. Cancel triggers and delete policies you don't recognize. Triggers created with a leaked key, including any that someone else created with it, keep firing until you cancel them.

To cancel, use DELETE /cancel by ID or custom key, a cancel by tag with /bulk, or the dashboard.

Triggers

The Triggers page lists your triggers, 20 per page. Each run of a recurring trigger is listed as its own trigger, an instance; the recurring trigger itself has no row.

Status. The chips filter the list: All (the default), Scheduled, Queued, Running, Retrying, Completed, Skipped and Cancelled. Scheduled is the API status registered; the other labels match the API names. See Trigger statuses for what each one means.

Completed doesn't mean successful. A trigger whose last attempt failed is Completed too. Check its result badge, or look for a DEAD badge on the trigger page.

Order:

  • All: Scheduled triggers first, the next one due at the top, then every other trigger, most recent activity first.
  • Scheduled: the next one due first.
  • Any other chip: most recent activity first.

A trigger's last activity is the latest of its due time and the times it was created, queued, started, completed or cancelled. Because the due time counts even when it's in the future, a cancelled trigger that was due in 3 days sorts near the top and shows "in 3 days".

The count of matching triggers ("N triggers") appears next to the chips, and the pager reads ← Previous, "Page X of Y", Next →.

Searching

Three search boxes narrow the list. They combine with each other and with the status chip:

BoxMatches
TitleText anywhere in the title, ignoring case. Needs at least 3 characters.
Custom keyText anywhere in the custom key, ignoring case. Needs at least 3 characters.
TagOne whole tag, exactly as written, case included.
  • The list updates 300 ms after you stop typing and goes back to page 1. Clear search empties all three boxes.
  • % and _ match themselves; they aren't wildcards.
  • While a Title or Custom key search is active, matches aren't counted: the page shows "N shown" (or "N+ shown") and the pager shows only the page number.

Instances of recurring triggers can't be found by custom key or title. The custom key belongs to the recurring trigger, and its instances have no custom key or title of their own. So the Title and Custom key boxes, like the Custom key filter on the Executions page, only find one-shot triggers. Give recurring triggers a tag and search by Tag instead: each instance gets the recurring trigger's tags when it's created.

Reading a row

From left to right, a row shows:

  • Status.
  • Result of the latest attempt: the HTTP status your target returned (green below 400, yellow for 4xx, red for 5xx; hover for its meaning). Without a response, a Completed trigger shows TIMEOUT or ERROR instead; hover for the error message. There's no badge before the first attempt, or while a retry is pending.
  • Method, title and URL: the title in bold, followed by the URL's host, path and query. Without a title, just the URL. Hover for the full URL.
  • Recurring badge, on instances only: the recurring trigger's custom key, or cron if it has none. Hover for "From generator …", with "(cancelled)" once the recurring trigger is cancelled.
  • Tags: up to 3, then "+N".
  • Duration of the latest attempt, and its lag, such as "+1.2s lag": the time between the trigger's due time and the start of its latest attempt. After a retry or a replay, the lag is still measured from the original due time, so it can be large.
  • Last activity, as a relative time. It starts with "ran" once the trigger has started, and with ⚠️ when a Scheduled trigger is past its due time.
  • → opens the trigger page.

On narrow screens, the recurring badge and the tags are hidden.

Click a row to expand it. You see the request (URL, title, trigger ID, custom key, the Generator an instance belongs to, tags, headers and the latest error), its lifecycle times and duration, a cancel button for Scheduled triggers, and the trigger's executions with Replay now or Retry now for Completed triggers.

Trigger page

The trigger page shows one trigger in full. Its header shows the status, the method and the title (or the custom key, or the URL if it has neither), and these buttons:

Request. Trigger ID, custom key, method, URL, tags, Generator (for an instance: the recurring trigger's custom key or ID, marked cancelled once it's cancelled) and Headers, the stored headers that are sent to your target. Headers are shown in full, credentials included.

Body. Shown as "Body (size)" when the trigger has a body:

  • The preview shows the first 200 KB. A longer body is marked TRUNCATED.
  • A complete body that is a JSON object or array is indented and marked JSON.
  • A body that isn't valid UTF-8 text shows "binary body (size) — no text preview". This can also happen to a text body over 200 KB.
  • Hover over the body for a Copy button.

Lifecycle. Created, Due at, then Queued, Started and Completed for the latest attempt, and Cancelled. Only the times that are set appear, each with a relative time. The latest attempt's error, if any, is shown below.

Executions (N). Every attempt, newest first, including one that is planned but not sent yet. Each row shows:

  • The attempt number: #1 is the first attempt.
  • What created it: scheduler, retry or replay. See Execution statuses.
  • DEAD for a dead letter.
  • The result: the HTTP status, TIMEOUT, ERROR, or, without a result, the execution status, such as planned.
  • When it started, and how long it took.

Click an attempt that has a response or an error to see the Error, the Response headers and the Response body. Only the first 10 KB of a response body is stored (see Response bodies); for a larger response, a note reads "(first 10 KB shown of N bytes)". The note can also appear on a short response that contains non-ASCII characters, even though it's shown in full.

The trigger page doesn't update by itself. It reloads after Cancel, Replay now or Retry now, and when you come back to the browser tab. Otherwise, reload the page to see new attempts.

Cancelling a trigger

You can cancel a Scheduled trigger from the dashboard:

  • On the Triggers page, expand the row and click Cancel trigger, or Cancel recurring trigger for an instance.
  • On the trigger page, click Cancel.

The trigger is cancelled immediately, without confirmation.

Instances of a recurring trigger. Cancelling an instance (the button reads Cancel recurring trigger) cancels the whole recurring trigger: that instance is cancelled and no more are created. Instances whose time has already come (Queued, Running, Retrying or Completed) aren't cancelled: Queued and Retrying ones still fire. This differs from DELETE /cancel with an instance's ID, which cancels only that instance; the recurring trigger then creates a new one for the same time within seconds.

Limitations:

  • The dashboard cancels Scheduled triggers only. To stop a Retrying trigger's pending retry, use DELETE /cancel with its trigger ID.
  • A Queued trigger can't be cancelled from the dashboard, or by ID or custom key. If it has a tag, a cancel by tag stops it, along with every other trigger with that tag. A Running trigger's request can't be stopped.
  • If the trigger moved on since the page loaded, for example because it fired, you get "Trigger not found or no longer cancellable".

Replay and retry

A Completed trigger has a Replay now or Retry now button, on its trigger page and in its expanded row on the Triggers page. Both send the trigger's stored request again, right away:

  • The button reads Retry now when the latest attempt ended with an error (such as a timeout or a network error) or an HTTP status of 400 or higher, and Replay now otherwise, including after a final 3xx.
  • Clicking adds a new attempt planned for now, and the trigger goes back to Queued. The request is usually sent within a second, with the same method, URL, headers and body.
  • The trigger's tag policies apply as for any attempt: throughput and concurrency limits can hold it back, and their timeout and retry settings are used.
  • Afterwards, the trigger is Completed again.
  • Replays don't use quota, and they work when your quota is used up.

The two buttons do the same thing. The only difference is the label of the new attempt: retry or replay.

Good to know

  • The attempt count continues. The new attempt gets the next attempt number, such as #4 after #1 to #3, and every attempt so far counts toward the tag policy's Max attempts. If the trigger has used all of its attempts, a replay that fails becomes a dead letter right away, without automatic retries. To give a replay retries, raise Max attempts on the tag policy, or clear it (blank = ∞), first.
  • Exponential backoff continues too. With a 10-second initial delay, a failed replay that is attempt #4 is retried after about 80 seconds, not 10.
  • Manual retries look like automatic ones. Retry now labels its attempt retry, like an automatic retry from a tag policy, and nothing else tells the two apart. replay always comes from Replay now.
  • Each replay is a real request. The button is disabled while your click is processed and disappears once the trigger is queued. But clicking it again in another tab that still shows it, once the first replay is in flight, sends the request a second time. See Delivery guarantees.

Executions

The Executions page lists attempts across all your triggers, 50 per page: scheduled runs, retries and replays. Each row is one attempt. Scheduled triggers have no attempts until they're due, and Skipped triggers never fire, so neither is listed here. Response headers and bodies are on the trigger page.

Attempts are sorted by last activity, newest first: when they finished, started or, if neither, were planned for. A pending retry is planned for a future time, so it's listed above attempts that already finished.

A row reads like a Triggers row, with these differences:

  • Status is the trigger's current status, not the attempt's.
  • Result is this attempt's: the HTTP status, TIMEOUT or ERROR, or, without a result yet, the execution status, such as planned. DEAD marks a dead letter.
  • Custom key of the trigger, on wide screens, in place of the recurring badge and tags.
  • What created the attempt and its number, such as "retry · #2".
  • Response size, shown as "≥10MB" once a response reaches the 10 MB read limit.
  • Lag is measured from the time the attempt was planned for, and shown only when it's at least a second.
  • Last activity: hover for the planned, start and finish times.

Filters:

FilterShows attempts
Job IDOf one trigger. Paste its full trigger ID.
Custom keyOf one-shot triggers whose custom key is exactly this, case included. Unlike on the Triggers page, part of a key doesn't match.
Job statusOf triggers that have this status now, not when the attempt ran. The values are API names: registered is Scheduled.
Execution statusWith this status: planned, started, complete or cancelled.
HTTP statusWhose response had this status class (2xx to 5xx) or code. Attempts without a response, such as timeouts, network errors and attempts not sent yet, never match.
Only dead lettersThat are dead letters: final failures with no retry to follow.
  • Filters combine, and the list goes back to page 1 when you change one. The text boxes apply 300 ms after you stop typing.
  • With a filter set, Clear filters and a match count appear. More than 10,000 matches show as "10,000+".
  • The page doesn't update live: click the refresh button to load new attempts.

Tag policies

Tag Policies manages the same policies as the /tag-policies API, with the same rules. The table has one row per tag, newest first, with the policy as badges:

BadgeMeaning
2/10sThroughput: at most 2 requests per 10 seconds. One badge per window; hover for an explanation. 0.2/1s means one request every 5 seconds, and a rate of 0 blocks the tag.
Concurrency 2 slotsConcurrency: at most 2 requests in flight.
Timeout 30 secRequest timeout.
retry ≤4× ·exp(5s)·5xx+netRetries: at most 4 attempts in all (∞× for no limit), exponential from 5 seconds (a fixed delay shows as, for example, 10s), on 5xx+net, net or non-2xx failures. Only shown when retries are on.
No policy setThe policy sets nothing.

Add policy opens a form:

  • Tag: lowercase letters, digits, - and _, up to 50 characters. What you type is lowercased. With any other character, the form doesn't submit and puts the cursor back in the field, without a message.
  • Throughput: + Add throughput rule adds a row "rate per n sec / min / hr / day". The rate can be a decimal; the window length is a whole number. ✕ removes a row, and a row without a rate is ignored. Each window can appear only once (60 sec and 1 min count as different windows). A hint under each row explains the rule.
  • Concurrency (slots) and Timeout (sec), whole numbers: leave them blank for no concurrency limit and the default 300-second timeout. The timeout ranges from 1 to 3600 seconds.
  • Retry policy: set the Strategy to Fixed delay or Exponential backoff to turn retries on (the default is None (no retries)). The other fields then appear:
    • Retry on: 5xx + network (default), Network errors only or Any non-2xx (incl. 4xx).
    • Max attempts (blank = ∞): includes the first attempt.
    • Delay between attempts (sec), or Initial delay (sec) for exponential backoff: required.
    • Max delay cap (sec): exponential backoff only.
    • Add jitter.
  • Click Create. Errors, such as a missing delay or a policy that sets nothing, appear in a red banner above the table.

Good to know

  • Adding a tag that already has a policy replaces that policy, without a warning.
  • Edit opens the policy in its row. The tag can't be changed. Save sends every field: a field you leave blank is cleared, and removing every throughput row removes the throughput limit. Unlike Create, Save accepts a policy that sets nothing.
  • Retry fields that are hidden after you change the Strategy keep their values, and those values are saved too.
  • Delete removes the policy immediately, without confirmation.
  • A change applies to triggers you scheduled earlier too, from their next attempt. See Tag policies.

Live updates

Only the Triggers page updates live. The indicator next to its refresh button reads Live when connected, Connecting while it connects or reconnects, and Offline otherwise. The browser reconnects by itself.

  • Rows on screen update their status, title and times as triggers move along. With a status chip or a title search active, a row that stops matching disappears.
  • Other triggers that are created or change are added at the top of the list, whatever the sort order, but only while you're on page 1 and only if they match your filters and search.
  • The executions in an expanded row don't update live: collapse and expand the row to reload them.

After a live update, a row loses its result badge, duration, lag and "ran" prefix until you click the refresh button or reload the page.

The other pages load their data when you open them and again when you come back to the browser tab. To see new data in between, reload the page, or click the refresh button on Executions.

Dates and times

  • Your time zone. The dashboard shows times in your browser's time zone, without a time zone label. The API works in UTC: a trigger due at 2030-01-01T09:00:00Z shows as Jan 1, 09:00:00 in London and Jan 1, 04:00:00 in New York.
  • Formats. Times use a 24-hour clock without the year, like Jan 1, 09:00:00. Hover over a time in a list, or in a trigger's lifecycle, for the full date, like Jan 1, 2030, 9:00:00 AM. API key creation dates use your browser's date format.
  • Relative times count seconds within a minute of now ("12 seconds ago", "in 5 seconds"), updating every second. Beyond that, a label such as "1 minute ago" or "in about 3 hours" doesn't update by itself: it changes when the page reloads its data or, on Triggers, gets a live update. A future time starts counting down again once it's a minute away.

Dashboard endpoints

The dashboard calls these endpoints of the API, which also appear in the full spec. They accept only a signed-in dashboard session: called with an API key, in ttr-api-keyheader or Authorization: Bearer, they return 401 with the message Unauthorized. They aren't part of the public API; see Dashboard-only endpoints.

EndpointUsed for
GET /keys, POST /keys, DELETE /keys/{id}The API Keys page
GET /jobsThe Triggers page and the trigger page
GET /jobs/{id}/executionsA trigger's executions
POST /jobs/{id}/executionsReplay now and Retry now
GET /executionsThe Executions page
  • GET /jobs takes status, id, title, customKey, tag, limit (default 50, at most 100) and offset. With title or customKey, the response's total is -1, meaning not counted. The 3-character minimum applies only in the dashboard.
  • GET /executions takes jobId, customKey, jobStatus, executionStatus, httpStatus (a code, or a class such as 4xx), deadLetterOnly=true, limit (default 50, at most 200) and offset. total stops counting at 10001.
  • POST /jobs/{id}/executions takes {"triggeredBy": "replay"} or {"triggeredBy": "retry"} ({} means replay) and returns {"ok": true}. Unlike the dashboard buttons, it doesn't check the trigger's status. On a trigger that hasn't fired yet, was skipped or was cancelled, it sends the request right away, and the trigger ends up Completed. On a Retrying trigger it sends nothing early, but it moves the trigger to Queued, so it can no longer be cancelled; the pending retry still fires at its time.

TimeTriggers — Schedule HTTP requests at any time.