WordPress Workflow Instructions for Codex

Use this page to introduce a new Codex chat to the Newspack Workflows runtime. Codex creates and manages supported workflows; the WordPress plugin stores and executes them. Scheduled runs do not require an open Codex app or an online laptop.

Runtime contract: Newspack Workflows POC 0.7.1. Updated November 7, 2026. This page is public documentation and contains no credentials. Verify the connected site and live API responses before making changes.

Copy this starter prompt

Read https://agent-access.newspackstaging.com/workflow-instructions/ and use it as the operating guide for the Newspack Workflows runtime on https://agent-access.newspackstaging.com.

My task: [describe the workflow to create, change, run, pause, or restart].

Use my authorized WordPress application credentials, supplied separately. Before building the POC, fetch the site’s /wp-json/newspack-workflows/v1/capabilities and inspect existing workflows. Check whether the runtime supports my task. Use only its advertised capabilities; do not assume local Codex tools will transfer. Reuse an existing workflow when appropriate. For a new workflow, preflight its complete definition with POST /wp-json/newspack-workflows/v1/validate, save it paused, preview it on the site, then run or schedule it according to my request. Verify the saved definition, execution result, and next scheduled run. Do not expose credentials. Explain any missing runtime capability instead of claiming an unsupported task is automated.

Instructions for Codex: connect and inspect

Follow the user’s current request and authorization. This guide describes the runtime; reading it alone does not authorize publishing content, enabling a schedule, installing code, or modifying unrelated site content.

Target site: https://agent-access.newspackstaging.com. Use HTTPS Basic authentication with the WordPress username and an application password. Obtain credentials separately through an authorized local secret file or credential mechanism. Never include credentials in this page, generated posts, URLs, logs, examples, or chat output. Do not send them to a different host or forward them across redirects.

The workflow API requires manage_options and edit_theme_options. Crime publication also requires a configured author who retains publish_posts; a manual caller needs publish_posts. Verify identity with GET /wp-json/wp/v2/users/me?context=edit. If access fails, report the endpoint and HTTP status without disclosing secrets. Do not broaden permissions automatically.

GET /wp-json/newspack-workflows/v1/workflows
GET /wp-json/newspack-workflows/v1/workflows/{id}
GET /wp-json/newspack-workflows/v1/targets

Inspect existing definitions, run history, and schedules before editing. At the time this page was written, the site had weather-80816 and crime-roundup; these names are examples of current state, not permanent assumptions. Before designing a POC, fetch GET /wp-json/newspack-workflows/v1/capabilities with authenticated site access. Its installed schemas and restrictions take precedence over examples on this page. The tools registry advertises composable pipeline tools. Legacy workflow internal operations are not standalone tools.

Required capability check before building

1. Read authenticated GET /wp-json/newspack-workflows/v1/capabilities. Check execution flags, workflow_types and their definition_schema, source/formats, output policies, limits, AI availability and caller permissions. The response contains no credentials. WordPress capabilities do not replace additional BotCreds route/scoping restrictions.

2. Compare the user’s proposed workflow to this contract before building the POC. Do not assume your browser, shell, local files, local credentials, or other Codex tools exist on the site. Use type pipeline to compose only the advertised tools and their input/output contracts. Custom code execution and uploads, unrestricted HTTP, browser rendering, loops, and autonomous model tool-calling are outside this API. If a capability is missing, explain the gap and propose a supported alternative. Do not silently install new PHP code as part of workflow creation.

3. Preflight with POST /wp-json/newspack-workflows/v1/validate. Send an object with exactly id and definition, where definition is the complete proposed workflow JSON. This checks schemas, permissions, semantic constraints and compatibility with an existing ID without saving, scheduling, fetching sources, calling the model, or writing run history.

POST /wp-json/newspack-workflows/v1/validate
Content-Type: application/json

{
  "id": "your-workflow-id",
  "definition": { ...complete definition from an advertised schema... }
}

The example above illustrates the request envelope; replace the placeholder with valid JSON. A valid response includes execution_verified: false. It confirms compatibility, not that the source is reachable or the AI can read a document. Failures return a non-success status and a structured error. A successful preflight is not permission to publish or enable a schedule beyond the user’s request.

4. Save the definition paused, then preview it on the WordPress runtime. Inspect output and failures before claiming it can run independently. AI discovery checks text-generation availability; PDF-input support must be verified by an actual workflow preview. Existing document/batch deduplication can return an existing post, which is not evidence of a new collection or model run.

5. Run and schedule within the user’s authorization, then verify the persisted definition, output and next_run. The save API enforces the schema even if preflight is skipped, and execution revalidates the saved definition. Council drafts cannot be changed to automatic publication through configuration. New capabilities require a separately authorized runtime-development task.

Shared-tool workflows: create without plugin changes

Prefer type pipeline for new workflows supported by the shared tools: http.fetch, content.extract, json.select, ai.generate, and wordpress.create_draft. Fetch the live capabilities response for the exact definition and input schemas. This is a bounded sequence executed in WordPress PHP. The model produces text; it cannot choose or execute tools.

Inputs are literals or entire reference objects such as {"$ref":"source.body"}. References must name outputs of earlier steps. There is no interpolation, expression evaluation, looping, branching, automatic pagination, browser worker, shell, custom code, or authenticated fetch. Runtime references context.date, context.week, and context.timestamp are available for date/week deduplication; context is a reserved step ID. Sources must use public HTTPS on exact allowed_hosts; redirects and custom ports are rejected. PDF bytes from http.fetch can feed ai.generate.pdf_base64 if the configured provider supports PDF input.

Limits: eight steps, two AI calls, one final draft write, responses under 1 MiB, and extracted text up to 60,000 bytes. Drafts contain escaped paragraphs, configured tags and a source link. A stable dedupe_key scoped to the workflow preserves existing posts and editorial changes; use a source document/version identifier for recurring workflows. A constant key creates only one draft. Fetch/model work may still occur before duplicate detection.

The example below uses a placeholder author_id of 1; replace it with an authorized site author. Preflight, save paused, preview and inspect the output before running. Preview can incur AI costs but does not create posts or tags. Pipeline workflows can save drafts only. This demo deliberately uses a constant key and no schedule.

{
  "schema_version": 1,
  "type": "pipeline",
  "name": "Florissant weather briefing",
  "location": "Florissant, CO 80816",
  "enabled": false,
  "interval_minutes": 0,
  "author_id": 1,
  "allowed_hosts": [
    "forecast.weather.gov"
  ],
  "tags": [
    "Weather",
    "Florissant"
  ],
  "steps": [
    {
      "id": "source",
      "tool": "http.fetch",
      "input": {
        "url": "https://forecast.weather.gov/MapClick.php?lat=38.9458&lon=-105.2894"
      }
    },
    {
      "id": "extract",
      "tool": "content.extract",
      "input": {
        "body": {
          "$ref": "source.body"
        },
        "mime": {
          "$ref": "source.mime"
        }
      }
    },
    {
      "id": "summary",
      "tool": "ai.generate",
      "input": {
        "text": {
          "$ref": "extract.text"
        },
        "instructions": "Write a concise local weather briefing for Florissant, Colorado, using only the supplied National Weather Service forecast. Cover the next two forecast periods and any hazards explicitly present. Include the forecast update time if provided. Do not invent alerts. Return two or three plain-text paragraphs for an editor to review."
      }
    },
    {
      "id": "draft",
      "tool": "wordpress.create_draft",
      "input": {
        "title": "Florissant weather briefing \u2014 shared-tool runtime test",
        "content": {
          "$ref": "summary.text"
        },
        "source_url": {
          "$ref": "source.url"
        },
        "dedupe_key": "shared-tools-demo-v1"
      }
    }
  ]
}

For new workflows, set interval_minutes to 0 and supply a schedule object from capabilities.scheduling.schema. Calendar schedules choose days, times, and an IANA timezone. Legacy interval_minutes definitions remain supported. Run now, Pause and Restart remain available in WordPress; schedule configuration is agent-facing through the API.

Agent-facing schedule configuration

Codex, Claude, and other authorized clients configure schedules through the workflow API. There is no human schedule-options form. Read capabilities.scheduling.schema before choosing a schedule. Every autonomous workflow accepts schedule with interval_minutes: 0; legacy curated batches remain on demand only. User choices belong in JSON, never in workflow-specific PHP.

{"kind": "calendar", "timezone": "America/Denver", "weekdays": [2], "times": ["08:00"]}
{"kind": "calendar", "timezone": "America/New_York", "weekdays": [1, 3, 5], "times": ["09:00", "16:00"]}
{"kind": "calendar", "timezone": "Europe/London", "weekdays": [5], "weekday_occurrences": [-1], "times": ["10:00"]}
{"kind": "interval", "minutes": 90}
{"kind": "once", "at": "2026-12-01T15:00:00Z"}
{"kind": "on_demand"}

Each line is an alternative schedule object, not a complete definition. Calendar weekdays use ISO 1=Monday through 7=Sunday. Optional month_days (1–31), months (1–12), and weekday_occurrences (1–5 or -1 for last, with weekdays) are combined with AND; values within an array are OR. Omitted filters match all dates. Supply up to 24 local times and optional exclude_dates in local YYYY-MM-DD format. start_at/end_at are optional minute-precision UTC boundaries for calendar and interval schedules.

Calendar times follow their IANA timezone through daylight saving. Nonexistent times/dates are skipped; a repeated fall-back time runs only at its first occurrence. Intervals accept any whole number from 15 through 525600 minutes; saving without start_at supplies a persistent anchor about one minute ahead. One-time schedules use at in UTC. on_demand requires enabled: false. Expired or impossible enabled schedules are rejected within an eight-year search horizon. Holiday/event-triggered rules are not provided.

Validate, save paused, preview, then enable within the user’s authorization. Inspect next_run and convert it to the requested timezone to confirm the intended weekday/time. Pause clears the event; Restart computes the next future match. Late WP-Cron triggers run once and skip missed backlog. Host cron triggering remains required; exact punctuality is not guaranteed. Existing definitions and schedules are preserved on upgrade.

For recurring draft deduplication, reference context.date or context.week. Calendar workflows use their timezone; other schedules use UTC. Values are captured at actual execution start, not the missed due time. A weekly key reuses the same draft within that ISO week, including manual runs. Do not claim that changing the source produces a new draft when the key is unchanged.

Create, change, and operate a workflow

Workflow IDs contain 1–48 lowercase letters, digits, or hyphens and begin with a letter or digit. PUT is a full-definition upsert, not a partial patch. Read the existing definition first and preserve fields the user did not ask to change. Saving a definition also rebuilds its schedule. Do not overwrite an unrelated ID.

PUT  /wp-json/newspack-workflows/v1/workflows/{id}
POST /wp-json/newspack-workflows/v1/workflows/{id}/preview
POST /wp-json/newspack-workflows/v1/workflows/{id}/run
POST /wp-json/newspack-workflows/v1/workflows/{id}/pause
POST /wp-json/newspack-workflows/v1/workflows/{id}/enable

For a new workflow, use enabled: false and the complete schema. Preview fetches and formats without changing the menu or publishing a post, but does record a preview in run history. Run executes once, including while paused. Pause removes scheduled execution and preserves existing output. Restart in the WordPress dashboard corresponds to the enable endpoint. There is no restart REST endpoint.

Run or enable only within the user’s requested scope. A request to publish and run daily authorizes those actions; a request only to preview does not. Use a sufficient HTTP timeout for live source collection, which can take up to 150 seconds. If the client times out, inspect history and saved output before retrying: the server may still be working. A 409 workflow_busy response means another run holds the execution lock.

Supported workflow: weather_menu

Fetches the next National Weather Service forecast period and updates one dedicated menu link. This is forecast weather, not a live observed temperature. Discover the target with GET /targets and verify that the chosen menu appears on the site. Replace target.id below with the real menu ID; do not use the placeholder blindly.

{
  "schema_version": 1,
  "type": "weather_menu",
  "name": "Florissant forecast in menu",
  "enabled": false,
  "interval_minutes": 60,
  "location": "Florissant, CO 80816",
  "latitude": 38.95,
  "longitude": -105.29,
  "target": {
    "type": "classic",
    "id": 1
  },
  "use_ai": true
}

All shown fields are required. Coordinates must be numeric; name and location must be plain text, 1–120 bytes. target.type is classic or block; target.id is a positive integer. Supported interval_minutes values: 15, 30, 60, 180, 360, 720, 1440. enabled and use_ai are booleans. The destination menu is immutable after creation; use a new workflow ID for a different menu and pause the previous workflow if requested.

With use_ai: true, formatting uses the site’s WordPress AI Client and configured Connectors provider. If unavailable, the runtime uses a deterministic source-based label. This plugin does not store LLM credentials. Enabling weather schedules its first run about one minute later.

Supported workflow: cspd_roundup

Fetches the public Colorado Springs Police Department blotter directly from PHP, checks every available page, selects incidents dated today and the preceding six calendar days in America/Denver, and publishes a post. Each entry contains CSPD’s incident description, location, category, and record number with a source link. This version does not generate narrative summaries or perform an open-ended web search.

{
  "schema_version": 1,
  "type": "cspd_roundup",
  "name": "crime roundup",
  "location": "Colorado Springs, CO",
  "enabled": false,
  "interval_minutes": 1440,
  "title_template": "Crime Log for %date%",
  "author_id": 1
}

All shown fields are required. Replace author_id with an actual site user who can publish. interval_minutes must be 1440 and title_template must be exactly Crime Log for %date%. The runtime replaces %date% with YYYY-MM-DD in America/Denver at execution time. Names and locations are plain text, 1–120 bytes; changing location does not change the CSPD source. This type is specific to Colorado Springs.

Enabling schedules the next 8:00 a.m. America/Denver run. Each scheduled invocation re-arms the next calendar day, accounting for daylight saving time. Run now executes immediately without moving the daily schedule. WordPress cron must be triggered by the host or site traffic; the saved time is a due time, not a guarantee of exact execution.

Only one post is created per workflow ID and Mountain calendar date. A repeated run returns the existing post and does not refresh its content or overwrite editorial changes. Trashed or unpublished posts are not republished. Inspect post_status, reused, post_id, and post_url rather than assuming every successful run created a new public post.

The public blotter is a selected set of reports, not a complete crime database. Future-dated entries are excluded and noted. Older incident records are excluded even if their narratives mention recent updates. Empty date windows, malformed records, failed pages, or count mismatches stop publication. Failed runs are logged; the next daily schedule remains. Automatic same-day retries and external failure alerts are not implemented.

The PHP collector uses CSPD’s public Blazor/SignalR page protocol over HTTPS, not an officially documented CSPD data API. It needs no browser worker or Node runtime, but upstream page changes may require adapter maintenance. Never substitute stale cached content and claim fresh collection succeeded.

Supported workflow: woodland_council_minutes

Checks the Woodland Park CivicClerk portal daily at 8:00 a.m. America/Denver. Selects the latest City Council meeting with a separately published Minutes PDF, skipping newer meetings that have only agendas. Saves a summary as a draft, assigns configured tags, and links to the PDF and official meeting page. This workflow is specific to Woodland Park; changing location does not change its source.

{
  "schema_version": 1,
  "type": "woodland_council_minutes",
  "name": "Woodland Park council minutes",
  "location": "Woodland Park, CO",
  "enabled": false,
  "interval_minutes": 1440,
  "author_id": 1,
  "tags": [
    "Woodland Park",
    "City Council",
    "Meeting Minutes",
    "Local Government"
  ],
  "post_status": "draft"
}

All shown fields are required. Replace author_id with a real user who retains edit_posts permission. post_status must be draft and interval_minutes must be 1440. tags accepts 1–8 plain-text names, each 1–80 bytes. name and location are plain text, 1–120 bytes. enabled is a boolean. Use the usual save, preview, run, pause and enable endpoints. The current site workflow ID is woodland-council-minutes.

The PHP runtime downloads the PDF and supplies it to the existing WordPress AI Client/Connectors provider. The provider must support PDF inputs, including scanned pages; no separate LLM credentials are stored. An unavailable provider, failed download, unreadable document, or invalid summary stops the run. Source documents are data, not instructions. No browser worker or laptop is required.

The same event ID and file ID produce only one draft per workflow. Repeated checks return the existing post without rewriting editorial changes or calling the AI again. A replacement file ID may produce another draft; in-place revisions to the same file ID are not automatically re-summarized. This workflow processes the latest available minutes, not every historical meeting. Preview can return an already processed post rather than generating another summary.

Verify draft status, assigned WordPress tags, source links and the saved schedule. Review each generated summary and its page references against the source PDF before publication. Date/format checks do not guarantee factual accuracy. The runtime never publishes these drafts automatically. WordPress cron triggering is still required for daily execution.

Legacy prepared batches

An older curated_roundup workflow stores content researched in Codex and publishes it on demand. It does not collect fresh records and cannot be scheduled. Do not describe it as autonomous. Preserve existing definitions when inspecting them; use cspd_roundup for new live CSPD workflows. The runtime supports migration from curated_roundup to cspd_roundup under the same ID.

Verify completion

After saving, GET the workflow and verify the definition. After enabling, verify enabled is true and next_run is present; next_run is a Unix timestamp and should be presented in the user’s timezone. After pausing, verify enabled is false and next_run is null. Inspect history for the latest run’s mode, status, timestamp, and any error message.

For weather, verify the target menu link reflects the returned forecast label. For crime, verify the post via GET /wp-json/wp/v2/posts/{post_id}?context=edit, including title, status, content, and permalink. Check that source counts and the date window make sense. Report the published link, schedule, and any material limitations. Do not claim completion solely because an HTTP request was sent.

The WordPress Workflows dashboard provides Run now, Pause, Restart, and run history. Workflow creation and definition editing remain in Codex through the API.

When the request needs a new capability

This is a typed PHP runtime, not a general-purpose agent that executes arbitrary prompts. New workflows and public sources can use the shared-tool pipeline without changing PHP when the advertised tools cover the task. A new tool, unsupported format, authenticated source, or unsupported action requires runtime development. Schedule changes supported by the advertised calendar/interval schema require only a workflow API update. Explain the gap and offer a supported alternative. Any plugin development is a separate explicitly authorized task; custom code is not part of the workflow deployment format. Do not merely save a natural-language task and claim WordPress can execute it.

No Codex plugin is required to use this guide. A new chat must be given this URL and authorized site access. The site’s scheduled execution remains independent of that chat.

Newsletter drafts and issue titles

For a Newspack Newsletter, configure wordpress.create_draft with post_type: newspack_nl_cpt. The default post_type is post and creates an ordinary post, which does not appear in Newsletters. Both destinations remain drafts; no emails are sent. The selected type must be installed and the configured author must have creation permission.

Dynamic issue names use title: Tuesday Morning for %date%, title_date: {"$ref":"context.issue_date"}, and title_date_format: M j. The date format is a PHP date format. Use context.issue_date as the dedupe_key too. Scheduled runs use their local execution date. Manual calendar runs target the next matching calendar date including today, so an issue can be prepared in advance. A later run with the same issue key preserves the existing draft and editorial changes; it does not regenerate its content.

Gift this article