Loading...
Loading...
16/5/26:2 - Openquok CLI (0.0.6) helps individuals or teams run many social accounts at scale with automation, drafts, scheduling, and human approval. Use when driving the `openquok` CLI (`@openquok/auto-cli`). Requires a globally installed CLI on the host (≥ 0.0.6 for hosted device login).
npx skill4agent add ratimon/openquok-monorepo openquok-core| Property | Value |
|---|---|
| name | openquok |
| description | AI-ready social scheduling: CLI-first |
| allowed-tools | Bash(openquok:*) |
npx skills add.agents/skills/openquokopenquokopenquok --version@openquok/auto-clinpm install -g @openquok/auto-cli@latestopenquok --version@openquok/auto-cliopenquok-m--mediaimage--jsonopenquok uploadopenquok upload-from-urlimage.jpg-midpathRESULT=$(openquok upload <file>)
MEDIA=$(echo "$RESULT" | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create ... -m "$MEDIA" ...-m "something.jpg"idpathfilePathopenquok upload something.jpgopenquokopenquok auth:statusexport OPENQUOK_API_KEY=opo_your_key_here
# or persist:
openquok auth:login --apiKey "opo_…"--jsonopenquok auth:login --jsonverification_uri_complete?code=/device/verifyopenquok auth:statusopenquok@openquok/auto-cliintegrations:triggeruploadupload-from-urlhttps://upload-from-url-mposts:createposts:statusanalytics:platformanalytics:post73090posts:missingposts:connect --release-id# 1. Authenticate
openquok auth:status
# If not authenticated (agents): openquok auth:login --json # or API key above
# 2. Discover
openquok integrations:list
openquok integrations:settings <integration-uuid>
# 3. Fetch (if needed)
openquok integrations:trigger <integration-uuid> <method> -d '{"key":"value"}'
# 4. Prepare
openquok upload ./image.jpg
# 5. Post (media: see Rule 2 — build JSON from upload response)
RESULT=$(openquok upload ./image.jpg)
MEDIA=$(echo "$RESULT" | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create -c "Content" -s "2026-01-01T12:00:00Z" -i "<integration-uuid>" -m "$MEDIA"
# 6. Analyze
openquok analytics:platform <integration-uuid> -d 30
openquok analytics:post <post-id> -d 7
# 7. Resolve (when the product surfaces a missing release / analytics gap)
openquok posts:missing <post-id>
openquok posts:connect <post-id> --release-id "<provider-release-id>"export OPENQUOK_API_KEY=opo_your_api_key_here
openquok auth:login --apiKey "opo_…" # optional: write ~/.openquok/credentials.json
openquok auth:status--jsonopenquok auth:login --json
openquok auth:status
openquok auth:logoutopenquok auth:login--json--json~/.openquok/credentials.jsonOPENQUOK_API_KEYauth:logoutexport OPENQUOK_API_URL=https://api.openquok.com
export OPENQUOK_AUTH_SERVER=https://cli-auth.openquok.comOPENQUOK_AUTH_SERVERhttp://localhost:3111agent/serveropenquok integrations:list
openquok integrations:settings <integration-uuid>
openquok integrations:trigger <integration-uuid> <method-name> [--data '<json>' | -d '<json>']integrations:list# Simple post (schedule time is required unless --json)
openquok posts:create -c "Content" -s "2026-01-01T12:00:00Z" -i "<integration-uuid>"
# Draft
openquok posts:create -c "Content" -s "2026-01-01T12:00:00Z" -t draft -i "<integration-uuid>"
# Post with media (upload each file first — Rule 2)
MEDIA=$(jq -s 'add' \
<(openquok upload ./img1.jpg | jq '[{id: .data.id, path: (.data.path // .data.filePath)}]') \
<(openquok upload ./img2.jpg | jq '[{id: .data.id, path: (.data.path // .data.filePath)}]'))
openquok posts:create -c "Content" -m "$MEDIA" -s "2026-01-01T12:00:00Z" -i "<integration-uuid>"
# Thread-style body (repeated -c); optional repeated -m pairs with leading segments (see `agent/README.md`)
MAIN=$(openquok upload ./main.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
C1=$(openquok upload ./comment1.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "Main post" -m "$MAIN" \
-c "First reply" -m "$C1" \
-s "2026-01-01T12:00:00Z" \
-i "<integration-uuid>"
# Multi-channel (comma-separated integration UUIDs)
openquok posts:create -c "Content" -s "2026-01-01T12:00:00Z" -i "<uuid-a>,<uuid-b>"
# Per-channel bodies
openquok posts:create \
-s "2026-01-01T12:00:00Z" \
-i "<uuid-a>,<uuid-b>" \
--bodiesByIntegrationId '{"<uuid-a>":"Short","<uuid-b>":"Longer caption"}'
# Platform-specific JSON (merge into each selected integration unless overridden)
openquok posts:create \
-c "Content" \
-s "2026-01-01T12:00:00Z" \
--settings '{"post_type":"post"}' \
-i "<integration-uuid>"
# Full payload from disk (must match POST /public/posts — see Technical Concepts)
openquok posts:create --json ./post.json# Defaults: 30 local calendar days before today through 30 after (override with --start/--end or --startDate/--endDate)
openquok posts:list
openquok posts:list --start "2026-01-01T00:00:00Z" --end "2026-02-01T00:00:00Z"
# Flip draft ↔ scheduled using a post row id from posts:list
openquok posts:status <post-id> --status draft
openquok posts:status <post-id> -s schedule
openquok posts:delete <post-id>openquok analytics:platform <integration-uuid> # default 7 days
openquok analytics:platform <integration-uuid> -d 30
openquok analytics:platform <integration-uuid> --days 90
openquok analytics:post <post-id>
openquok analytics:post <post-id> -d 30--days-djqopenquok analytics:post <post-id>
openquok posts:missing <post-id>
openquok posts:connect <post-id> --release-id "<provider-release-id>"
openquok analytics:post <post-id>openquok upload ./image.jpg
openquok upload-from-url "https://cdn.example.com/banner.png"data.iddata.pathdata.filePath[{id, path}]-mopenquok uploadjqidopenquok upload-from-url-minstagram-standaloneinstagram-businessoutput.toolsintegrations:settingsintegrations:triggerTH_ID=$(openquok integrations:list | jq -r '.[] | select(.identifier=="threads") | .id')
openquok integrations:settings "$TH_ID"
# Replace METHOD with a name from output.tools[].methodName; adjust -d to match dataSchema.
openquok integrations:trigger "$TH_ID" METHOD -d '{}'IG_STANDALONE_ID=$(openquok integrations:list | jq -r '.[] | select(.identifier=="instagram-standalone") | .id')
openquok integrations:settings "$IG_STANDALONE_ID"
IG_BUSINESS_ID=$(openquok integrations:list | jq -r '.[] | select(.identifier=="instagram-business") | .id')
openquok integrations:settings "$IG_BUSINESS_ID"METHOD-doutput.tools[].methodNamedataSchematoolsVIDEO=$(openquok upload ./video.mp4 | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
THUMB=$(openquok upload ./thumbnail.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
MEDIA=$(jq -s 'add' <(echo "$VIDEO") <(echo "$THUMB"))
openquok posts:create \
-c "Check out my video!" \
-m "$MEDIA" \
-s "2026-01-01T12:00:00Z" \
-i "<integration-uuid>"-ddelaySecondsINTRO=$(openquok upload ./intro.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
P1=$(openquok upload ./point1.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "Thread starter (1/3)" -m "$INTRO" \
-c "Point one (2/3)" -m "$P1" \
-c "Conclusion (3/3)" \
-s "2026-01-01T12:00:00Z" \
-d 60000 \
-i "<integration-uuid>"openquok uploadupload-from-urlINTRO=$(openquok upload ./intro.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
P1=$(openquok upload ./point1.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
P2=$(openquok upload ./point2.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
OUTRO=$(openquok upload ./outro.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "Thread starter (1/4)" -m "$INTRO" \
-c "Point one (2/4)" -m "$P1" \
-c "Point two (3/4)" -m "$P2" \
-c "Conclusion (4/4)" -m "$OUTRO" \
-s "2026-01-01T12:00:00Z" \
-d 2000 \
-i "<integration-uuid>"integrations:listPOST /public/postscat > campaign.json << 'EOF'
{
"scheduledAt": "2026-01-01T12:00:00.000Z",
"status": "scheduled",
"body": "Default caption",
"integrationIds": ["<uuid-a>", "<uuid-b>"],
"bodiesByIntegrationId": {
"<uuid-a>": "Short version for channel A",
"<uuid-b>": "Longer version for channel B"
},
"media": [
{ "id": "<from upload>", "path": "<from upload>" }
],
"providerSettingsByIntegrationId": {
"<uuid-a>": {},
"<uuid-b>": {}
}
}
EOF
openquok posts:create --json ./campaign.jsonmediauploadintegrations:settings#!/usr/bin/env bash
INTEGRATION_ID="<integration-uuid>"
CONTENT="Your post content here"
SETTINGS_JSON=$(openquok integrations:settings "$INTEGRATION_ID")
MAX_LENGTH=$(echo "$SETTINGS_JSON" | jq '.output.maxLength')
if [ "${#CONTENT}" -gt "$MAX_LENGTH" ]; then
echo "Content exceeds $MAX_LENGTH chars, truncating..."
CONTENT="${CONTENT:0:$((MAX_LENGTH - 3))}..."
fi
openquok posts:create \
-c "$CONTENT" \
-s "2026-01-01T12:00:00Z" \
-i "$INTEGRATION_ID"#!/usr/bin/env bash
DATES=("2026-02-14T09:00:00Z" "2026-02-15T09:00:00Z" "2026-02-16T09:00:00Z")
CONTENT=("Monday motivation" "Tuesday tips" "Wednesday wisdom")
for i in "${!DATES[@]}"; do
MEDIA=$(openquok upload "post-${i}.jpg" | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "${CONTENT[$i]}" \
-s "${DATES[$i]}" \
-i "<integration-uuid>" \
-m "$MEDIA"
done#!/usr/bin/env bash
CONTENT="Your post content"
INTEGRATION_ID="<integration-uuid>"
DATE="2026-01-01T12:00:00Z"
MAX_RETRIES=3
for attempt in $(seq 1 "$MAX_RETRIES"); do
if openquok posts:create -c "$CONTENT" -s "$DATE" -i "$INTEGRATION_ID"; then
echo "Post created successfully"
break
fi
echo "Attempt $attempt failed"
if [ "$attempt" -lt "$MAX_RETRIES" ]; then
sleep $((2 ** attempt))
else
exit 1
fi
doneintegrations:settingsoutput.tools[]methodNamedescriptiondataSchemaintegrations:trigger <uuid> <methodName> [-d '<json object>']{ "output": ... }threadsinstagram-standaloneinstagram-businessintegrations:settingsoutput.toolsintegrations:trigger--settingsproviderSettingsByIntegrationId-irepliesdelaySeconds-c-dintegrations:settings-cbodyreplies-mmediaagent/README.mdagent/tests/e2e/-s--scheduledAtposts:create--start--end--startDate--endDateposts:listsuccessmessage{
"data": {
"id": "media-id",
"path": "storage/path/or/url",
"filePath": "alternate-field-name"
}
}jqpathfilePath--settings--json-jPOST /public/postsbodiesByIntegrationIdproviderSettingsByIntegrationIdmediaopenquok integrations:settings <uuid>openquok posts:create \
-c "Launch post" \
-s "2026-01-01T12:00:00Z" \
-i "<threads-uuid>"https://threadsProviderassertThreadsSupportedMediatest -f ./hero.jpg && test -s ./hero.jpg
IMAGE=$(openquok upload ./hero.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "Shipped today 🚀" \
-m "$IMAGE" \
-s "2026-01-01T12:00:00Z" \
-i "<threads-uuid>"instagram-standaloneidentifierinstagram-standaloneIMAGE=$(openquok upload ./image.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "Caption #hashtag" \
-s "2026-01-01T12:00:00Z" \
--settings '{"post_type":"post"}' \
-m "$IMAGE" \
-i "<instagram-standalone-uuid>"
STORY=$(openquok upload ./story.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "" \
-s "2026-01-01T12:00:00Z" \
--settings '{"post_type":"story"}' \
-m "$STORY" \
-i "<instagram-standalone-uuid>"instagram-businessidentifierinstagram-businesspost_typeintegrations:settingsIMAGE=$(openquok upload ./image.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')
openquok posts:create \
-c "Caption #hashtag" \
-s "2026-01-01T12:00:00Z" \
--settings '{"post_type":"post"}' \
-m "$IMAGE" \
-i "<instagram-business-uuid>"openquok upload-from-urlopenquok upload ./fileupload-from-urlhttps://posts:statusbackend/integrations/providers/threadsProvider.tsresolvePublicMediaUrlcreateSingleMediaContentthreads_publishContent-Length: 0openquok auth:login --jsonOPENQUOK_API_KEYverification_uri_completeopenquok auth:login --jsonverification_uri_completeintegrations:listintegrations:settings-mmedia[]idpathuploadupload-from-url-mContent-Length: 0--settings '{"post_type":"post"}'posts:create-s--jsonscheduledAtintegrations:triggeroutput.toolsoutput.maxLengthintegrations:settingsoutput.toolsintegrations:settings-dposts:create73090OPENQUOK_API_KEYauth:logoutauth:loginnpm install -g @openquok/auto-cli@latestwww.openquok.comnpx skills addopenquok --version# Authenticate first (agents: --json or API key; humans locally may omit --json)
openquok auth:status
openquok auth:login --json
openquok auth:logout
export OPENQUOK_API_KEY=opo_...
# Discovery
openquok integrations:list
openquok integrations:settings <uuid>
openquok integrations:trigger <uuid> <method> -d '{}'
# Media (Rule 2)
openquok upload ./file
openquok upload-from-url "https://…"
# Posting
openquok posts:create -c "text" -s "2026-01-01T12:00:00Z" -i "<uuid>"
openquok posts:create -c "text" -s "2026-01-01T12:00:00Z" -t draft -i "<uuid>"
openquok posts:create -c "text" -s "2026-01-01T12:00:00Z" -i "<uuid>" -m "$(openquok upload ./img.jpg | jq -c '[{id: .data.id, path: (.data.path // .data.filePath)}]')"
openquok posts:create -c "main" -c "reply" -s "2026-01-01T12:00:00Z" -i "<uuid>"
openquok posts:create --json ./post.json
# Management
openquok posts:list
openquok posts:status <post-id> --status draft
openquok posts:status <post-id> -s schedule
openquok posts:delete <post-id>
# Analytics & recovery
openquok analytics:platform <uuid> -d 30
openquok analytics:post <post-id> -d 7
openquok posts:missing <post-id>
openquok posts:connect <post-id> --release-id "<id>"
# Help
openquok --help
openquok posts:create --help