# Publishing posts

This page describes how to create workflows for publishing posts, reposting, and mentioning people and companies in post text.

## Creating a post

To publish a post, you need to include [`st.createPost`](/docs/action-st-create-post) action in your workflow. Here's an example:

**Workflow:**

```json
{
  "actionType": "st.createPost",
  "text": "We shipped our new onboarding flow this week."
}
```

**Completion:**

```json
{
  "actionType": "st.createPost",
  "success": true,
  "data": {
    "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:1234567890123456789",
    "postUrn": "urn:li:activity:1234567890123456789"
  }
}
```

## Reposting

To repost an existing post, you need to include [`st.createRepost`](/docs/action-st-create-repost) action in your workflow. Without `text` the post is reposted as is; with `text` your commentary is published above it. Here's an example:

**Workflow:**

```json
{
  "actionType": "st.createRepost",
  "postUrl": "https://www.linkedin.com/posts/post1",
  "text": "Worth reading, especially the part on onboarding."
}
```

**Completion:**

```json
{
  "actionType": "st.createRepost",
  "success": true,
  "data": {
    "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:2345678901234567890",
    "postUrn": "urn:li:activity:2345678901234567890"
  }
}
```

The returned identifiers belong to the repost itself, which is a post of your own account. They are what you pass to further post actions if you want to engage with the repost rather than with the original.

> `postUrl` and `postUrn` are `null` when the repost was published but LinkedIn did not return its address. Do not retry: the repost is already live.

> `alreadyReposted` is returned only when LinkedIn refuses an instant repost (one without `text`). LinkedIn does not always refuse a repeat repost: a repost of your own post, or a repost with commentary, can be published again. Keep track of what you have already reposted instead of relying on this error.

Reposts count toward the same posting limit as [`st.createPost`](/docs/action-st-create-post).

## Mentions

Both [`st.createPost`](/docs/action-st-create-post) and [`st.createRepost`](/docs/action-st-create-repost) accept a `mentions` array. Each item binds a placeholder in the text to one person or company: write `@[key]` where the mention should appear, and describe that `key` in `mentions`. Here's an example:

**Workflow:**

```json
{
  "actionType": "st.createPost",
  "text": "Huge thanks to @[author] and everyone at @[company] for the launch.",
  "mentions": [
    {
      "key": "author",
      "name": "Example Person",
      "personHashedUrl": "https://www.linkedin.com/in/ACwAAAxxxxxxxxx"
    },
    {
      "key": "company",
      "name": "Example Company",
      "urn": "urn:li:organization:1234567"
    }
  ]
}
```

Each item accepts:

- `key` (required) – the placeholder name used in the text as `@[key]`. From 1 to 30 characters: letters, digits, `_` or `-`.
- `name` (required) – the name to find the person or company by, from 1 to 100 characters.
- `urn` (optional) – [URN](/docs/core-concepts#linkedin-urns) of the entity: `urn:li:member:<id>` for a person, `urn:li:organization:<id>` for a company.
- `personHashedUrl` (optional) – hashed LinkedIn profile URL of the person.
- `companyHashedUrl` (optional) – hashed LinkedIn company page URL.

Provide at most one of `urn`, `personHashedUrl` and `companyHashedUrl`.

The workflow is rejected before anything is published when:

- more than **20** mentions are supplied;
- the text refers to a `@[key]` that is not among the mentions;
- a mention is supplied whose `@[key]` does not appear in the text;
- two mentions share the same `key`.

> `name` is required even when you provide an identifier, because LinkedIn resolves a mention through its own name suggestions. The identifier decides which of the offered namesakes is taken; without one, the first suggestion LinkedIn ranks is used, which is not guaranteed to be the person or company you meant. If none of the suggestions match, the action fails with `mentionNotResolved` and nothing is published.

> The published mention shows LinkedIn's own name for the entity, which may differ from the `name` you sent.

## Addressing a post by URN

Post actions accept `postUrn` instead of `postUrl`, so identifiers returned by one action can be passed straight into the next without building a URL. This works for [`st.openPost`](/docs/action-st-open-post), [`st.createRepost`](/docs/action-st-create-repost), [`st.reactToPost`](/docs/action-st-react-to-post), [`st.commentOnPost`](/docs/action-st-comment-on-post), [`st.retrievePostComments`](/docs/action-st-retrieve-post-comments) and [`st.retrievePostReactions`](/docs/action-st-retrieve-post-reactions). Here's an example:

**Workflow:**

```json
{
  "actionType": "st.reactToPost",
  "postUrn": "urn:li:activity:1234567890123456789",
  "type": "like"
}
```

Provide one of the two. If you provide both, the URL must contain that same URN, otherwise the workflow is rejected.

## Publishing and engaging in one workflow

[`st.createPost`](/docs/action-st-create-post) accepts [`st.openPost`](/docs/action-st-open-post) as a child action, which lets you act on the post you have just published. Here's an example that publishes a post and leaves the first comment under it:

**Workflow:**

```json
{
  "actionType": "st.createPost",
  "text": "We shipped our new onboarding flow this week.",
  "then": {
    "actionType": "st.openPost",
    "basicInfo": false,
    "then": {
      "actionType": "st.commentOnPost",
      "text": "Details and screenshots in the comments below."
    }
  }
}
```

**Completion:**

```json
{
  "actionType": "st.createPost",
  "success": true,
  "data": {
    "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:1234567890123456789",
    "postUrn": "urn:li:activity:1234567890123456789",
    "then": {
      "actionType": "st.openPost",
      "success": true,
      "data": {
        "then": {
          "actionType": "st.commentOnPost",
          "success": true,
          "data": {
            "commentUrn": "urn:li:comment:(urn:li:activity:1234567890123456789,1122334455)",
            "commentUrl": "https://www.linkedin.com/feed/update/urn:li:activity:1234567890123456789/?dashCommentUrn=urn%3Ali%3Afsd_comment%3A(1122334455%2Curn%3Ali%3Aactivity%3A1234567890123456789)"
          }
        }
      }
    }
  }
}
```

> `postUrl` and `postUrn` are `null` when the post was published but LinkedIn did not return its address. In that case the child actions in `then` did not run, so the comment above would not be left. Do not retry: the post is already live.

> This page provides examples of [workflows](/docs/building-workflows) and their [completions](/docs/executing-workflows). For detailed documentation on constraints, parameters, and possible results of specific actions, always refer to the corresponding [action documentation pages](/docs/actions-overview).
