Omni Automation Script & Keyboard Maestro Macro: Schedule and Defer Tags in OmniFocus


In OmniFocus, tags can be marked as Available or On Hold manually. However, there is no built-in way to defer a tag until a certain date or to set a schedule for a specific tag’s status.

There are several scenarios where this might be useful. For example:

  • I use tags to represent people. If, for example, my boss or colleague is away for the week and I have a number of items to speak to them about, I cannot do so until next week so these tasks should not show as ‘available’ but I don’t want to have to defer them all manually. Similarly, as I write this I’m on a bizarre sleep schedule (awaiting labour!) and my partner is in bed, so I don’t want to worry about any of the tasks that require his input.
  • I use tags to represent locations where I might carry out errands e.g. the pharmacy, the supermarket, or the hardware store. These places are not open 24/7, so if I’m looking at my OmniFocus database late at night these tasks are not available and I don’t want to see them.
  • I use tags to represent broad times of day. For example, I have a ☀️ Morning tag for tasks that it makes more sense to do in the morning – something like putting the bed linen in the washing machine so that I don’t have to worry about finding another set to sleep in!


OmniFocus set-up

I have set up a project in OmniFocus called Tag Scheduling. This contains meta “scheduler” tasks which contain the information needed to schedule the tags.

These tasks have the following attributes:

  • Name starts with AVAILABLE or DEFERRED (and is usually followed by a description of when the defer date will be reached e.g. AVAILABLE from 8/1/20 or DEFERRED from 5pm Mon-Fri.
  • Project is Tag Scheduling
  • Tag is the tag to be scheduled.
  • Defer date is the time that the tag should become available or be placed on hold.

These tasks can be relatively simple, one-off occurrences (like the aforementioned example where my partner has gone to bed for the night):

However, I can also use repeating “scheduler” tasks to represent things like the opening hours of our local library or recurring time periods:

(Note that in these cases it is important to watch the repeat settings carefully: you probably want to make sure you are using the Assigned Dates option.)

OmniFocus plugin

The plugin has two actions: one checks to see whether any tags need to be updated, and does so. It can be run manually, but is more effectively when paired with something like the Keyboard Maestro macro below.

The second prompts me for a tag and a date and then effectively “defers” the tag to that date by creating the necessary scheduler task as outlined above. It doesn’t handle the more complex repeating schedules but is a quick and easy way to defer a single tag. It’s what I used to create the simple example above (best of all, OmniFocus’ date smarts work in these forms):

UPDATE 2021-01-30: The plugin has now been updated so that it now allows you to select multiple tags to defer. If tags are selected in OmniFocus, these will be auto-selected in this form. In addition, the actual deferral of a tag is handled by a function in the plugin’s library, which means you can more easily defer tags from other plugins or scripts. (For example, if I mark a task tagged with “washing machine” complete, the “washing machine” tag is put on hold for a while using my “Custom Complete” plugin, because I can’t do a second load while the first one is still running.)

Keyboard Maestro macro

It’s all well and good to be able to update the state of tags manually, but ideally these are triggered on a schedule, and that’s where Keyboard Maestro comes in. Essentially, I’ve created a simple macro (downloadable below) which runs this Omni Automation action automatically every 10 minutes so my tags stay up to date:

This can be automatically “allowed” as a trusted script in OmniFocus which means it doesn’t need my input to run. The only caveat is that it does briefly jump to an OmniFocus window every half an hour – but, at least for me, this hasn’t been an issue; it’s usually open anyway!

UPDATE 2021-02-20: Initially this Keyboard Maestro macro made use of a URL to run the Omni Automation script; the downside of this was that it drew focus to OmniFocus briefly each time. Ken Case pointed out in the Omni Slack channel that a script can instead be run by AppleScript, which happens in the background. The macro has now been updated to use this instead as it is much nicer!

The Script & Macro

The OmniFocus plugin can be download from GitHub here. (At that link you will find installation instructions.)

The Keyboard Maestro macro can be downloaded here: Run OF Plugin: Update Tag Status.

8 thoughts on “Omni Automation Script & Keyboard Maestro Macro: Schedule and Defer Tags in OmniFocus”

  1. Hello Kaitlin,

    after discovering your “multi-dependency” plugin last week, I’ve been playing with this one as well.

    These two are by far the most useful plugins or scripts I’ve found anywhere for OmniFocus 3. Really appreciate your work!

    I have also gotten the KeyboardMaestro macro to work – it makes a big difference not having to manually run the update tags action.

    And this got me wondering: Could you perhaps also provide a macro like this for the dependency tag plugin? I tried adapting the script myself, but wasn’t able to get it to trigger the “Check Prerequisites” action.

    Best regards,

    1. Hi Adrian! So glad you’re finding them both useful.

      1. I’ve actually tweaked the KM macro to use a slightly different method (the post has been updated) which I prefer because OmniFocus doesn’t steal focus. So you might benefit from re-downloading that one!

      2. That’s no trouble at all, I’ve created one using the same method and added it to the dependency post here:

      1. Hi Kaitlin,

        many thanks, the script works flawlessly! I’ve also downloaded the new version for the multi-dependency script – it does work even better than before 🙂

        Since you seem to be open to ideas, I want to make a suggestion for another script: Would it be possible to implement a functionality similar to “defer tags”, but for projects?

        For example, if there’s an entire project that is only actionable on weekends, then it would be great if it could be set to “on hold” during the week and made active automatically on weekends.


        1. Of course, always open to ideas!

          That would definitely be possible, and it should be fairly straightforward to adapt the Defer Tags script to do this. I’ll add it to my list and let you know if I put it together!

          1. Hi Kaitlin,

            just wanted to follow up, since I would still be very interested in this modified script.

            In case you ever get around to creating it, I would be a big fan 🙂


          2. Hi Adrian

            Definitely still on the list! I had a baby in January so I’ve been a little distracted, but I promise I’ll let you know. 🙂

  2. Fair enough, that’s a very valid reason to delay a random request from someone on the internet 🙂 Maybe the existing ‘defer tags’ script could be adapted to also work with projects, similar to how this is now possible for the dependency script

    1. Hi again Adrian! I’ve been playing with this and there is now a branch of this on Github that allows you to defer a project alongside a tag:

      It requires the notation $DEFERWITHTAG=Tag Name to be included in the project’s note.

      When that is there:
      – the Defer Tag action will also set the project to on hold
      – when the tag is updated to available/deferred by the ‘Update Timed Tags’ action, the project will also be updated

      I’ve avoided using tasks inside the projects to represent the timings, because they would potentially block the other tasks, especially in a sequential project. That would be okay if we only wanted to defer the tag one time, but I think for a repeating use case like ‘weekends’ it would be problematic. (I think if we just wanted to defer the project once, we would use the built-in defer date anyway.)

      I also assumed that using the actual tag to tag the project was undesirable, because it would automatically be applied to any new tasks in that project, but as a result of it I believe the update script is quite a bit slower to run. (Happy to take any other suggestions here. Maybe it would be better to use preferences to store this somehow, so that only a limited number needed to be checked, but I haven’t played with that part of the Omni Automation API yet.)

      Right now it only works with one tag. Do you think there is a use case for 2+? (That would be slightly more complicated, I think, because when a tag became available, it would need to check whether ANY of the current tags were on hold, and if so leave the project on hold.)

      Have a play and let me know your thoughts. 🙂

Leave a Reply