# How to Post to Social Media from a Cron Job or GitHub Actions
Author: Davis Baer
Author URL: https://www.oneupapp.io/blog/author/davis-baer
Published: 2026-10-12
Meta Description: How to post to social media from a cron job or GitHub Actions using OneUp's REST API, with a shell script and a release-announcement workflow.
URL: https://www.oneupapp.io/blog/how-to-post-to-social-media-from-a-cron-job-or-github-actions

Not every social post starts with someone opening a scheduler. A weekly tip can go out from a cron job, and a release announcement can fire when a build finishes. OneUp's REST API makes both possible with a single `curl` call. Here's how to set them up.

## What you need

- Your OneUp API key, from the API Access page
- A category ID and the account IDs you want to post to. Get them from the `listcategory` and `listcategoryaccount` endpoints, as shown in our [command-line scheduling guide](https://www.oneupapp.io/blog/how-to-schedule-social-media-posts-from-the-command-line).

OneUp passes the API key as an `apiKey` query parameter, so treat it like a password. Keep it in a secrets store or a locked-down environment file, never in the script itself.

## A reusable shell script

Save this as `post.sh`. It schedules a text post ten minutes from now and fails loudly if OneUp reports an error:

```bash bash
#!/usr/bin/env bash
set -euo pipefail

response=$(curl -sS -G -X POST "https://www.oneupapp.io/api/scheduletextpost" \
  --data-urlencode "apiKey=${ONEUP_API_KEY}" \
  --data-urlencode "category_id=${ONEUP_CATEGORY_ID}" \
  --data-urlencode "social_network_id=[\"${ONEUP_ACCOUNT_ID}\"]" \
  --data-urlencode "scheduled_date_time=$(date -d '+10 minutes' '+%Y-%m-%d %H:%M')" \
  --data-urlencode "content=$1")

if ! echo "$response" | jq -e '.error == false' > /dev/null; then
  echo "OneUp returned an error: $response" >&2
  exit 1
fi

echo "$response"

```

A few notes:

- `date -d` is GNU date, so this works on Linux. On macOS, use `date -v+10M` instead.
- OneUp expects `YYYY-MM-DD HH:MM`. Check the API docs for how that time is interpreted against your account's timezone before relying on it for time-sensitive posts.
- The documented success response includes `"error": false`, which is what the `jq` check looks for.

## Running it from cron

Put the variables in a file only your user can read:

```bash bash
chmod 600 /etc/oneup.env

```

Then call the script from your crontab, for example every Monday at 9 AM:

```
0 9 * * 1 . /etc/oneup.env && /usr/local/bin/post.sh "Monday tip: schedule your week in one sitting."

```

This keeps the key out of the crontab and out of process listings.

## Running it from GitHub Actions

This workflow announces a release when it's published. The key lives in a repository secret, and the release details are passed through environment variables rather than pasted into the script:

```yaml yaml
name: Announce release
on:
  release:
    types: [published]

jobs:
  announce:
    runs-on: ubuntu-latest
    steps:
      - name: Schedule announcement on OneUp
        env:
          ONEUP_API_KEY: ${{ secrets.ONEUP_API_KEY }}
          ONEUP_CATEGORY_ID: ${{ vars.ONEUP_CATEGORY_ID }}
          ONEUP_ACCOUNT_ID: ${{ vars.ONEUP_ACCOUNT_ID }}
          RELEASE_NAME: ${{ github.event.release.name }}
          RELEASE_URL: ${{ github.event.release.html_url }}
        run: |
          response=$(curl -sS -G -X POST "https://www.oneupapp.io/api/scheduletextpost" \
            --data-urlencode "apiKey=${ONEUP_API_KEY}" \
            --data-urlencode "category_id=${ONEUP_CATEGORY_ID}" \
            --data-urlencode "social_network_id=[\"${ONEUP_ACCOUNT_ID}\"]" \
            --data-urlencode "scheduled_date_time=$(date -d '+10 minutes' '+%Y-%m-%d %H:%M')" \
            --data-urlencode "content=${RELEASE_NAME} is out: ${RELEASE_URL}")
          echo "$response" | jq -e '.error == false' > /dev/null

```

Passing release data through `env` instead of interpolating it directly into the `run` block avoids shell injection from untrusted text like release names.

## Keep the key safe

- Don't run `curl` with `-v` or other debug flags in a shared pipeline, since the key is part of the request URL.
- Rotate the key if it ever appears in a log.
- Use a repository secret or your CI's secret store, not a plain variable.

## Catch failures

A scheduled post can still fail later on a specific network. After important runs, check OneUp's failed-posts endpoint ( `getfailedposts`) or ask a connected coding agent to list failed posts and reschedule them.

## Posting images and video

Swap the endpoint for `scheduleimagepost` (with an `image_url`) or `schedulevideopost` (with a `video_url`). The reference docs list the full parameters.

Ready to automate your posting? [Read OneUp's API documentation](https://docs.oneupapp.io/).


---
This blog is powered by Superblog. Visit https://superblog.ai to know more.
---

