# X Article Publisher

> Run X Article Publisher by x online or via API. $0.15-$0.30/task, 1 call (draft only) or 2 calls (draft + publish), no setup.

**URL:** https://inference.sh/apps/x/article-publish
**Last updated:** 2026-08-11

---

Publish long-form articles on X.com from markdown. Supports headings, lists, blockquotes, code blocks, GFM tables, LaTeX, images, embedded tweets, and inline formatting (bold, italic, strikethrough, links). Optional cover image and draft-only mode.

- app: `x/article-publish`
- maker: [x](https://inference.sh/apps/x.md)
- category: [social](https://inference.sh/apps/category/social.md)
- tasks: [social media](https://inference.sh/apps/tag/social-media.md)
- price: $0.15-$0.30/task, 1 call (draft only) or 2 calls (draft + publish)
- runs via: api, javascript and python sdk, belt cli, mcp

## article-publish API Guide

### About
publish long-form articles on x.com from markdown. supports headings, lists, blockquotes, code blocks, gfm tables, latex, images, embedded tweets, and inline formatting (bold, italic, strikethrough, links). optional cover image and draft-only mode.

### Get an API Key
Create one in [settings → api keys](https://app.inference.sh/settings/keys). The examples read it from `INFERENCE_API_KEY`.

```bash
export INFERENCE_API_KEY="inf_your_key"
```

### 1. Calling the API

#### Install the Client

```bash
pip install inferencesh
```

#### Run and Get Result
Submit a request and wait for the final result.

```python
import os
from inferencesh import inference

client = inference(api_key=os.environ["INFERENCE_API_KEY"])

## version @3h32wavd pinned
result = client.run({
        "app": "x/article-publish@3h32wavd",
        "input": {
            "title": "title",
            "content": "content"
        }
    })

print(result["output"])
```

#### Stream Live Updates
Get real-time progress updates as the task runs.

```python
import os
from inferencesh import inference

client = inference(api_key=os.environ["INFERENCE_API_KEY"])

## version @3h32wavd pinned
## stream=True yields updates as they arrive
for update in client.run({
        "app": "x/article-publish@3h32wavd",
        "input": {
            "title": "title",
            "content": "content"
        }
    }, stream=True):
    if update.get("progress"):
        print(f"progress: {update['progress']}%")
    if update.get("output"):
        print(f"output: {update['output']}")
```

#### Run in the Background
Start the task and get its id back right away, then check on it with `GET /tasks/{id}`. It is done when `status` is 10 (completed), 11 (failed) or 12 (cancelled).

```python
import os
from inferencesh import inference, TaskStatus

client = inference(api_key=os.environ["INFERENCE_API_KEY"])

## returns as soon as the task is created
task = client.run({
        "app": "x/article-publish@3h32wavd",
        "input": {
            "title": "title",
            "content": "content"
        }
    }, wait=False)

## later: read its current state
state = client.tasks.get(task["id"]).data
if state["status"] == TaskStatus.COMPLETED:
    print(state["output"])
```

### 2. Files

#### Automatic Upload

```python
## local file paths are automatically uploaded
result = client.run({
    "app": "x/article-publish@3h32wavd",
    "input": {
        "image": "/path/to/local/image.png",  # detected & uploaded
        "audio": "https://example.com/audio.mp3",  # url passed through
    }
})
```

#### Manual Upload

```python
## upload and get a hosted URL
file = client.files.upload("/path/to/file.png")
print(file.uri)  # https://cloud.inference.sh/...
```

### 3. Schema

#### Input
- **title** (string) *required*: Article title (headline)
- **content** (string) *required*: Article body in markdown. Supports # headings, **bold**, *italic*, ~~strikethrough~~, `code`, [links](url), lists, blockquotes, fenced code blocks, GFM tables, $$LaTeX$$, horizontal rules. Reference uploaded media as ![alt](file:0), ![alt](file:1). Embed tweets as {{tweet:ID}}.
- **cover_image** (string): Cover image displayed at the top of the article
- **media** (array): Media files referenced in content as file:0, file:1, etc. Supports images (JPG, PNG, WEBP, GIF) and video (MP4).
- **publish** (boolean): Publish immediately. Set false to save as draft only.

#### Output
- **article_id** (string): ID of the created article
- **post_id** (string): ID of the post created on publish
- **post_url** (string): URL of the post created on publish
- **published** (boolean): Whether the article was published
- **title** (string): Article title

## other social apps

- [X Post Analytics](https://inference.sh/apps/x/post-analytics.md): $0.15/call
- [X Trending Topics](https://inference.sh/apps/x/trends.md): $0.15/call
- [X Following List](https://inference.sh/apps/x/following-list.md): $0.15/call
- [X Followers List](https://inference.sh/apps/x/followers-list.md): $0.15/call
- [X Post Likers](https://inference.sh/apps/x/post-likers.md): $0.15/call

## faq

### how much does X Article Publisher cost?

$0.15-$0.30/task, 1 call (draft only) or 2 calls (draft + publish). you pay per run from your inference shell credits. no subscription is required.

### how do I run X Article Publisher via api?

call x/article-publish with the javascript or python sdk, the rest api, or `belt app run x/article-publish` from a terminal. the api reference on this page lists every input.

### who makes X Article Publisher?

X Article Publisher is made by x and runs on inference shell. every x app is listed at https://inference.sh/apps/x.

### can my agent use X Article Publisher?

yes. agents call it as a tool through the inference shell mcp server (https://api.inference.sh/mcp), the belt cli or the sdk, and pay per run like you do.

### what are the alternatives to X Article Publisher?

other social apps on inference shell include X Post Analytics, X Trending Topics, X Following List, X Followers List. they run through the same api, so switching is a one-line change.
