cd /news/ai-agents/how-to-automate-scheduled-x-posts-wi… · home topics ai-agents article
[ARTICLE · art-99080] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

How to Automate Scheduled X Posts with Codex and xurl

A developer built a scheduled X publishing workflow using OpenAI's Codex and the official X API command-line client, xurl. The system separates editorial decisions made by the AI agent from deterministic publishing actions, with a skill owning the write boundary and a scheduled task enforcing timing and editorial policy. The architecture includes four layers and was verified in August 2026.

read10 min views1 publishedAug 16, 2026

Most social-media automation tutorials stop at “call the API on a cron job.” That works, but it leaves the hard questions unanswered. Which account is the automation using? How does it avoid posting the same story twice? What happens when an API request times out after X has already accepted the post? And where should an AI agent’s editorial freedom end?

I recently built a scheduled X publishing workflow with Codex and xurl

, the official command-line client for the X API. The result is not just a timer attached to an AI prompt. It is a small publishing system with four distinct layers:

xurl

, which stores the credentials and communicates with the X API.That separation is the important part. Codex can make editorial decisions, but it cannot casually choose an account or improvise the publishing command. The skill owns the deterministic write boundary, while the scheduled task owns timing and editorial policy.

In this article, I’ll show you how to build the same architecture.

X developer settings, API packages, Codex features, and command-line options can change. The workflow below was verified in August 2026, but you should check the current upstream documentation before using it in production.

Before starting, you will need:

You should also decide what the automation is allowed to publish before you give it access to an account. A good editorial policy is specific enough to reject a story, not merely broad enough to describe a topic.

For example, I built one version of this workflow for a health-news account. Its policy covered metabolic health, nutrition research, and evidence quality. It also required the agent to distinguish association from causation, label animal studies and preprints, avoid personalized medical advice, and prefer primary sources. Those rules mattered just as much as the code.

Install the official X Developer Platform CLI with Homebrew:

brew install --cask xdevplatform/tap/xurl

Then verify that it is available:

command -v xurl
xurl version

The xurl project supports OAuth 2.0 user authentication, multiple applications and accounts, shortcuts for common X actions, media uploads, and raw X API requests. Most importantly for this workflow, it gives us simple commands for identifying the authenticated user, reading account history, and creating a post.

Open the X Developer Console and create an application for the account you intend to manage.

Configure user authentication with these general settings:

Setting Value
App permissions Read and write
App type Web App, Automated App, or Bot
Callback URI http://localhost:8080/callback
Website URL A valid website you control
Environment A production-capable API package

The callback URI must match exactly. xurl

uses http://localhost:8080/callback

by default, although it can store a different redirect URI for an application if necessary.

When X asks how you will use its data, describe the real first-party workflow. A suitable statement might explain that the application will create original or scheduled posts, read the account’s own history to prevent duplicates, and retain only minimal operational data such as post IDs, source URLs, timestamps, and publishing status.

X exposes several credentials that look interchangeable but are not:

Save the OAuth 2.0 Client ID and Client Secret privately. Never paste them into a Codex conversation, a Markdown file, a screenshot, or your source repository.

Credential setup should happen in a private Terminal controlled by you, not inside an agent session. This zsh pattern prevents the literal secret from being recorded in shell history:

read "XURL_CLIENT_ID?Client ID: "
read -s "XURL_CLIENT_SECRET?Client Secret: "; echo

xurl auth apps add my-x-app \
  --client-id "$XURL_CLIENT_ID" \
  --client-secret "$XURL_CLIENT_SECRET" \
  --redirect-uri http://localhost:8080/callback

unset XURL_CLIENT_ID XURL_CLIENT_SECRET

Now authorize the intended account. Replace my_handle

with the handle without the @

character:

xurl auth oauth2 --app my-x-app my_handle
xurl auth default my-x-app my_handle

The OAuth command opens a browser. Sign in to the correct X account and approve the requested access.

Next, verify the setup without publishing anything:

xurl auth status
xurl whoami --username my_handle
xurl posts my_handle -n 100 --username my_handle

The whoami

result must contain the exact account you expect. If it does not, stop. Do not “test” the configuration by sending a post from an uncertain identity.

Also, never ask an agent to inspect or print anything under ~/.xurl/

. That directory contains authentication material. Avoid xurl --verbose

in an agent session as well, because verbose request output can expose sensitive headers.

Codex skills package repeatable instructions and optional executable logic. According to the OpenAI skill documentation, a skill is a directory with a required SKILL.md

file and optional scripts, references, assets, and interface metadata.

For this workflow, create a personal skill named something like xurl-post

:

xurl-post/
├── SKILL.md
├── agents/
│   └── openai.yaml
└── scripts/
    └── post.py

You can invoke $skill-creator

in Codex and describe what you want:

Create a personal skill named xurl-post. Use the locally installed xurl CLI
to publish finalized text and optional uploaded media from my_handle on X.
Support fully automated use, but verify the account before every write.

Why use a script instead of putting the command directly in SKILL.md

? Because this is exactly where deterministic behavior is valuable. Research and writing benefit from judgment. Account selection and argument construction do not.

The wrapper script should enforce the following rules:

xurl

executable.xurl whoami --username my_handle

before every post.xurl post TEXT --username my_handle

.--media-id

values for media that has already been uploaded.--dry-run

mode that checks identity and request construction without posting.The final rule deserves emphasis. If a request reaches X but the response is lost, the command may look like it failed even though the post exists. An automatic retry can therefore create a duplicate. After an ambiguous result, read the newest account history before doing anything else.

Your skill instructions should also define authorization clearly. A request to publish, post, send, or automate finalized copy can authorize a write. A request to draft, revise, review, or preview should not.

Do not publish “test 123” to a production account just to see whether the integration works.

Instead, validate the skill with its dry-run mode or with a simulated xurl

executable. Test at least these cases:

whoami

fails or returns malformed data.Once those tests pass, use one real, editorially valid post as the end-to-end production test.

The skill knows how to publish safely, but it should not decide what to publish. That belongs in the scheduled task’s saved prompt.

A dependable prompt should tell Codex to perform the following sequence on every run:

$xurl-post

exactly once.The saved prompt must be self-contained. Do not rely on the agent remembering a policy you mentioned in a different conversation.

Here is a reusable starting point:

On every run, read the articles in this project to refresh the site's subjects
and voice. Retrieve the full accessible post history for @my_handle before
choosing a topic. Find one timely story from an authoritative primary source
that fits the editorial policy below. Compare the source publication date with
the date of the underlying event or research. Reject exact duplicates and
semantically equivalent prior posts, even if their wording or URLs differ.

Write one concise, accurate, source-linked X post. Invoke $xurl-post exactly
once without requesting interactive confirmation. Report the source, exact
published text, duplicate check, and resulting post ID or URL. If history
retrieval, research, or factual verification fails, skip the run and explain
why. Never retry an ambiguous publishing result without first checking the
newest account history.

Editorial policy:
- [Your topic boundaries]
- [Your source-quality requirements]
- [Claims or language to avoid]
- [When to label uncertainty]
- [Any required disclosures]

In Codex, create the scheduled task in plain language and attach it to the relevant project. For example:

Create a scheduled task for this project that runs every day at 8:00 AM,
1:00 PM, and 6:00 PM Central. Use the complete research, duplicate-checking,
editorial, and publishing workflow in the prompt above.

Use the Codex Scheduled interface to review, edit, , resume, or remove the task. Background tasks can make file, network, and application changes according to their permissions, so keep the task’s sandbox and command rules as narrow as the workflow allows. OpenAI’s current Scheduled tasks documentation is the best place to check the latest behavior and requirements.

Preventing identical text is easy. Preventing repeated stories is harder.

Before researching or publishing, retrieve up to 100 recent posts:

xurl posts my_handle -n 100 --username my_handle

If the API response provides a pagination token, continue through as much history as your access permits. Build a duplicate index from more than the post text:

For each candidate story, search history using distinctive title terms, the source domain, named entities, and the main claim. A new article about an old study is not necessarily a new story.

Most importantly, make duplicate checking fail closed. If account history cannot be retrieved or checked reliably, the task should skip the run. Missing one scheduled post is much cheaper than eroding trust with duplicates.

This rule proved its value in my own health-news workflow. One run found a timely story, discovered that an equivalent post already existed, and skipped publishing. That was not a failed run; it was the system working correctly.

Before leaving the task unattended, test it in increasingly consequential stages:

https://x.com/my_handle/status/POST_ID

. the task immediately if it drifts from the editorial policy, repeats stories, relies on weak sources, or overstates what a source supports.

Automation does not eliminate editorial responsibility. It merely moves that responsibility into the prompt, the skill boundary, and the monitoring process.

Reauthorize using the explicit handle, then reset the defaults:

xurl auth oauth2 --app my-x-app my_handle
xurl auth default my-x-app my_handle
xurl whoami --username my_handle

Confirm that the X application has Read and write permission and belongs to a usable production API package. If you changed its scopes, repeat OAuth so the new authorization receives the updated permissions.

If authentication succeeds but whoami

returns client-forbidden

or client-not-enrolled

, check the application’s package and production enrollment in the X Developer Console. The current xurl README includes up-to-date enrollment troubleshooting.

The sandbox may block network access until a narrow permission is granted. Perform the first read-only and publishing tests interactively, then allow only the commands the scheduled workflow actually needs. Do not approve arbitrary shell or scripting access just to make unattended posting convenient.

Do not retry immediately. Fetch the newest posts and compare the exact text, canonical source URL, and core claim. Retry only after confirming X did not create the post.

Check that:

xurl

is still available in the task environment. the scheduled task before changing credentials, account settings, or the publishing skill.

To remove the integration completely, revoke the application in X and clear local xurl

authentication from your private Terminal:

xurl auth clear --all

If a Client Secret, token, or authentication header ever appears in chat, logs, screenshots, or documentation, rotate or revoke it immediately. Deleting the copied text is not enough; the exposed credential must no longer be valid.

The best part of this architecture is not that an AI can post on a schedule. The best part is that each component has one clear job.

xurl

owns authentication. The Codex skill owns identity verification and the write operation. The scheduled prompt owns research and editorial judgment. Account history provides a feedback loop for duplicate prevention and ambiguous failures.

That separation turns a fragile cron job into a publishing workflow you can reason about. The agent is free to decide that there is nothing worth posting today—and the safest automation is often the one that knows when to do nothing.

This story was originally published at blog.designly.biz on August 16, 2026.

── more in #ai-agents 4 stories · sorted by recency
── more on @codex 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-automate-sche…] indexed:0 read:10min 2026-08-16 ·