---
title: "as_schedule_single_action: Signature & Parameters"
description: "as_schedule_single_action documentation: full PHP signature, the timestamp and $unique parameters, return value, and code examples for delayed jobs."
url: "https://wpwebhooks.org/blog/as-schedule-single-action-reference/"
date: "2026-07-10"
---

# as_schedule_single_action: Signature & Parameters

**TL;DR:** `as_schedule_single_action()` queues a one-time background job that fires at a specific Unix timestamp by calling `do_action( $hook, ...$args )`.

-   Signature: `as_schedule_single_action( int $timestamp, string $hook, array $args = [], string $group = '', bool $unique = false, int $priority = 10 )`
-   Returns the integer action ID from `wp_actionscheduler_actions`; with `$unique = true` it returns the existing ID instead of inserting a duplicate.
-   It is the persistent, retryable equivalent of `wp_schedule_single_event()` — backed by database tables, not the `cron` option.

/ Signature

## What is the **as\_schedule\_single\_action** signature?

[`as_schedule_single_action()`](https://actionscheduler.org/api/#function-reference--as_schedule_single_action) schedules one background action to run once, at or after a given Unix timestamp. It is a global function shipped with [Action Scheduler](https://actionscheduler.org/), the background-job library maintained by WooCommerce and bundled inside WooCommerce, Jetpack, and hundreds of other plugins. When the scheduled time arrives, the queue runner calls `do_action( $hook, ...$args )`, so the code that actually runs is an ordinary WordPress hook callback registered with [`add_action()`](https://developer.wordpress.org/reference/functions/add_action/).

PHP — as\_schedule\_single\_action full signature

```
as_schedule_single_action(
    int    $timestamp,           // Unix time of the earliest run
    string $hook,                // action hook fired via do_action()
    array  $args     = [],       // args spread into the callback
    string $group    = '',       // label for filtering / bulk cancel
    bool   $unique   = false,    // skip if an identical action is pending
    int    $priority = 10        // 0-255, lower runs first (AS 3.5+)
): int;  // returns the action ID, or 0 on failure
```

The `$unique` parameter was added in Action Scheduler 3.3.0 and `$priority` in 3.5.0. On older bundled versions those trailing arguments are simply ignored, so passing them is safe but has no effect until the host site ships a recent enough copy.

/ Parameters

## What does each **as\_schedule\_single\_action** parameter do?

The first two arguments are required; the rest are optional. Getting `$args` and `$group` right matters most, because they are what the deduplication and cancellation functions match on.

| Parameter | Type | Purpose |
| --- | --- | --- |
| `$timestamp` | int | Earliest Unix time to run. The action fires on the first queue pass at or after this moment — not exactly on it. |
| `$hook` | string | The action hook name. Register a callback with `add_action( $hook, … )` or nothing runs. |
| `$args` | array | Values spread into the callback as `do_action( $hook, ...$args )`. Keep it small — args are serialised into the row. |
| `$group` | string | Free-text label used to filter in the admin UI and to bulk-cancel with `as_unschedule_all_actions()`. |
| `$unique` | bool | When true, skip insertion if a pending/running action with the same hook, args and group already exists. |
| `$priority` | int | 0–255 (default 10). Lower numbers are claimed first within the same timestamp. Added in AS 3.5.0. |

/ Timestamp

## How precise is the **$timestamp** argument?

The timestamp is a floor, not an alarm clock. Action Scheduler runs a queue on each WP-Cron pass (or Action Scheduler's own runner), claims a batch of actions whose `scheduled_date` is in the past, and executes them. So an action set for `time() + 5` runs on the first queue pass after those five seconds — which could be a few seconds late on a busy site, or longer if no traffic triggers WP-Cron. If you need clock-aligned execution (always at 06:00), use `as_schedule_cron_action()` instead; if you need it to run as soon as possible with no delay target at all, use [`as_enqueue_async_action()`](https://wpwebhooks.org/blog/action-scheduler-api-functions/).

FIG 01 — Lifecycle of a single scheduled action

/ Return value

## What does **as\_schedule\_single\_action** return?

It returns the integer action ID — the primary key of the new row in the `wp_actionscheduler_actions` table. Store it if you plan to cancel or inspect the action later. Two edge cases change what you get back:

1.  **Duplicate skipped.** When `$unique = true` and a matching pending or in-progress action already exists, the call returns that _existing_ action's ID and inserts nothing.
2.  **Failure.** If the action store cannot save the row, the function returns `0`. Treat a falsy return as "not scheduled" rather than assuming success.

> Every scheduled action maps to a WordPress hook. When the action runs, Action Scheduler calls `do_action($hook, ...$args)` — the callback is just a normal hook handler. — Action Scheduler usage guide

/ Deduplication

## How does **$unique** prevent duplicate single actions?

Passing `$unique = true` makes the scheduling call idempotent: before inserting, Action Scheduler looks for a pending or running action with the same hook, the same serialised `$args`, and the same group. If one exists, no new row is created. This is the race-safe way to guarantee "at most one queued job" for an event, because the check and the insert happen inside the same call rather than in your application code. The matching is exact, though — a different argument value, order, or type counts as a distinct action. For the guard-based alternative and the exact matching rules, see [preventing duplicate scheduled actions](https://wpwebhooks.org/blog/action-scheduler-prevent-duplicate-actions/).

PHP — schedule one delayed, deduplicated webhook

```
// Deliver a webhook 30s after checkout — but only once per order
$action_id = as_schedule_single_action(
    time() + 30,
    'myplugin_deliver_order_webhook',
    [ 'order_id' => $order_id ],
    'order-webhooks',
    true            // unique: repeated saves won't queue a 2nd delivery
);

add_action( 'myplugin_deliver_order_webhook', function( $order_id ) {
    $order = wc_get_order( $order_id );
    wp_remote_post( 'https://example.com/hook', [
        'body' => wp_json_encode( $order->get_data() ),
    ] );
} );
```

/ vs WP-Cron

## How is it different from **wp\_schedule\_single\_event**?

Both schedule a one-time hook, but the storage and reliability differ sharply. [`wp_schedule_single_event()`](https://developer.wordpress.org/reference/functions/wp_schedule_single_event/) stores every event in a single serialised `cron` row in `wp_options`, runs on visitor page loads, keeps no history, and never retries. `as_schedule_single_action()` stores one row per action, is claimed by a dedicated queue runner, retries failures, and logs every attempt.

| Feature | wp\_schedule\_single\_event | as\_schedule\_single\_action |
| --- | --- | --- |
| Storage | One serialised cron option row | One DB row per action, indexed |
| Trigger | Visitor page loads (WP-Cron) | Dedicated queue runner batch |
| Retry | None — one attempt | Automatic retry on failure |
| History | None once it runs | Full attempt log in wp-admin |
| Dedup | Manual — read the cron array | $unique = true, race-safe |
| Cancel | wp\_unschedule\_event by timestamp | as\_unschedule\_action by hook/args/group |

/ In practice

## Do you call **as\_schedule\_single\_action** for webhooks directly?

Usually not. Firing an outbound webhook when a WordPress or WooCommerce event happens is _event-driven_, not time-delayed: you hook `do_action` and POST on the event itself, ideally behind a queue that adds retry with exponential backoff and a delivery log. You reach for `as_schedule_single_action()` in your own code when you need a _delayed_ one-off job that is not a webhook: a reminder email, a cleanup pass, a deferred API sync. For the full function family — async, recurring, cron, query and cancel — see the [Action Scheduler PHP API reference](https://wpwebhooks.org/blog/action-scheduler-api-functions/).

## Structured data

```json
{"@context":"https://schema.org","@type":"Article","headline":"as_schedule_single_action: Signature & Parameters","description":"as_schedule_single_action documentation: full PHP signature, the timestamp and $unique parameters, return value, and code examples for delayed jobs.","datePublished":"2026-07-10","dateModified":"2026-07-10","author":{"@type":"Person","name":"Mateusz Skorupa","url":"https://wpwebhooks.org/about/"},"publisher":{"@type":"Organization","name":"WP Webhooks","url":"https://wpwebhooks.org"},"url":"https://wpwebhooks.org/blog/as-schedule-single-action-reference/","image":"https://wpwebhooks.org/og_image.jpg","keywords":["as schedule single action","as schedule single action signature","as schedule single action parameters","action scheduler single action","as schedule single action unique","as schedule single action return value"]}

{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"WP Webhooks","item":"https://wpwebhooks.org/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://wpwebhooks.org/blog/"},{"@type":"ListItem","position":3,"name":"as_schedule_single_action: Signature & Parameters","item":"https://wpwebhooks.org/blog/as-schedule-single-action-reference/"}]}

{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"What is the signature of as_schedule_single_action?","acceptedAnswer":{"@type":"Answer","text":"as_schedule_single_action( int $timestamp, string $hook, array $args = [], string $group = '', bool $unique = false, int $priority = 10 ) and it returns the integer action ID. The first two arguments — the Unix timestamp and the hook name — are required; the rest are optional. $unique was added in Action Scheduler 3.3.0 and $priority in 3.5.0."}},{"@type":"Question","name":"What does as_schedule_single_action return?","acceptedAnswer":{"@type":"Answer","text":"It returns the integer action ID — the primary key of the new row in wp_actionscheduler_actions. When $unique is true and a matching pending or in-progress action already exists, it returns that existing action ID without inserting a duplicate. If the row cannot be saved it returns 0, so a falsy return means the action was not scheduled."}},{"@type":"Question","name":"Does the action run exactly at the timestamp?","acceptedAnswer":{"@type":"Answer","text":"No. The timestamp is the earliest time the action can run, not an exact alarm. Action Scheduler executes it on the first queue pass at or after that moment, which can be a few seconds late on a busy site or longer if no traffic triggers the queue. For clock-aligned execution use as_schedule_cron_action instead."}},{"@type":"Question","name":"How is as_schedule_single_action different from wp_schedule_single_event?","acceptedAnswer":{"@type":"Answer","text":"Both schedule a one-time hook, but as_schedule_single_action stores one indexed row per action in dedicated database tables, is run by a dedicated queue runner, retries on failure, and logs every attempt. wp_schedule_single_event stores events in a single serialised cron option, runs on visitor page loads, keeps no history, and never retries."}},{"@type":"Question","name":"How do I stop as_schedule_single_action creating duplicates?","acceptedAnswer":{"@type":"Answer","text":"Pass $unique = true as the fifth argument. Before inserting, Action Scheduler checks for a pending or running action with the same hook, serialised args, and group; if one exists it returns that ID instead of creating a second row. Because the check and insert happen in one call, it is race-safe."}}]}
```
