OmniSocialsOmniSocials
DocumentationAPI reference
Help centerSupport
  • Documentation
  • API reference
Developers
  • Quickstart
  • API reference
  • SDKs
  • MCP server
  • CLI
For AI agents
  • Docs for AI agents
  • llms.txt
  • OpenAPI spec
  • Postman collection
Product
  • OmniSocials
  • Pricing
  • Changelog
  • Help center
Company
  • Support
  • Privacy policy
  • Terms of service

© 2026 OmniSocials

OmniSocials on GitHubOmniSocials on XOmniSocials on LinkedIn
Overview
Get started
SDKs
    Node.jsPythonGoRubyJavaPHP.NETRust
CLI
MCPDocs for AI agentsWebhooks
Guides
Platforms
Integrations
Migrate
Plans and billing
GlossaryChangelogAPI reference
SDKs

Ruby SDK reference: install, auth and methods

The official Ruby SDK. Ruby 3.0+, zero runtime dependencies (Net::HTTP, OpenSSL, JSON), plain-Hash responses.

This page is the reference. For an overview of the Ruby SDK, see omnisocials.com/sdk/ruby.

Install

TerminalTerminal
gem install omnisocials

Or in your Gemfile:

Ruby
gem "omnisocials"

Authentication

Ruby
require "omnisocials" client = OmniSocials::Client.new(api_key: "omsk_live_...") # or: export OMNISOCIALS_API_KEY=omsk_live_... and just OmniSocials::Client.new

Create a post

Ruby
post = client.posts.create( content: "Big announcement coming Friday", channels: ["instagram", "facebook", "linkedin"], scheduled_at: "2026-08-01T09:00:00Z", media_urls: ["https://example.com/teaser.jpg"] )

Any media_urls (or media_ids) entry can also be a Hash carrying per-media alt text (max 1500 chars), delivered to Mastodon, Bluesky, X (photos), Pinterest, Instagram (images), and LinkedIn (images):

Ruby
media_urls: [{ "url" => "https://example.com/teaser.jpg", "alt" => "Red sneaker on a white background" }]

Publish immediately:

Ruby
post = client.posts.create_and_publish( content: "We are live!", channels: ["x", "bluesky"] )

Upload media

Ruby
media = client.media.upload_from_url( url: "https://example.com/promo.mp4", name: "promo-august", folder: "Campaigns" ) media_id = media["data"]["id"]

Local files: client.media.upload(file: "/path/to/image.jpg", name: "hero-shot") (file accepts a path String/Pathname, an IO, or a raw binary String). Base64: client.media.upload_from_base64(data: b64_string, mime_type: "image/png").

Analytics

Ruby
# One post stats = client.analytics.post("123") # Up to 100 posts in one request (avoids rate limit trouble when syncing) bulk = client.analytics.posts(["123", "124", "125"]) # Workspace overview overview = client.analytics.overview(period: "30d") # Account-level stats (followers etc.) accounts = client.analytics.accounts(platform: "instagram")

Social Inbox

Read and answer DMs, comments and mentions from your connected accounts. The API key needs the opt-in inbox:read / inbox:write scopes. The lists use cursor pagination (cursor: in, pagination["next_cursor"] out).

Ruby
conversations = client.inbox.list_conversations(platform: "instagram", unread: true) conversation_id = conversations["data"][0]["conversation_id"] messages = client.inbox.get_messages(conversation_id) client.inbox.reply(conversation_id, text: "Thanks for reaching out!") client.inbox.mark_read(conversation_id) # Comment moderation: hide (hide: false unhides) or delete client.inbox.hide(messages["data"][0]["id"]) client.inbox.delete_message(messages["data"][0]["id"])

inbox.next hands out the next conversation that still needs an answer, with the thread and the post it belongs to. On a comment thread, pass message_id: so the reply goes under the comment you answer and not under the newest comment on the post.

Ruby
item = client.inbox.next while item["data"] message = item["data"]["message"] unless item["data"]["reply_window"]["open"] # An Instagram/Facebook DM past Meta's 24-hour window: answer it in the app client.inbox.mark_read(message["conversation_id"]) item = client.inbox.next next end reply = client.inbox.reply( message["conversation_id"], text: "Thanks! DM sent.", message_id: message["id"], include_next: true ) item = { "data" => reply["next"], "remaining" => reply["remaining"] || 0 } end

See the Social Inbox guide for the platforms, the reply rules and the error codes.

Pinterest product tags

Tag products on a Pin so people can shop the items in the image. List the product Pins of the connected Pinterest account, then pass up to 24 of their Pin ids as "product_tags" in the pinterest: options of the post. Only product Pins of your own account can be tagged; products of other merchants cannot.

Ruby
result = client.pinterest.list_products if result["error"] warn "#{result["error"]["code"]}: #{result["error"]["message"]}" else client.posts.create( content: "Our summer picks", channels: ["pinterest"], media_urls: ["https://example.com/summer-look.jpg"], scheduled_at: "2026-08-01T09:00:00Z", pinterest: { "board_id" => "1234567890", "product_tags" => result["products"].first(3).map { |product| product["pin_id"] } } ) end

The list answers with HTTP 200 in both cases: "products" on success, or an "error" hash (pinterest_not_connected, pinterest_catalog_access_required, platform_error) when it could not be read. It reads the Pinterest catalog when the connection has catalog access (given one time in the OmniSocials composer: Pinterest options, Add products, Connect catalog), else the account's own Pins. The tags are added right after the Pin is published. A product that Pinterest refuses never fails the post: the post then carries pinterest["product_tags_result"] with the tagged and the skipped Pin ids. client.pinterest.validate_product(id) checks one Pin id or Pin link before you post. On posts.update the pinterest: hash replaces the stored one, so leave "product_tags" out to remove the tags.

Verify webhooks

Rails controller:

Ruby
class OmnisocialsWebhooksController < ApplicationController skip_before_action :verify_authenticity_token def create payload = request.body.read # raw body, exactly as received signature = request.headers["X-OmniSocials-Signature"] begin event = OmniSocials::Webhooks.verify( payload: payload, signature: signature, secret: ENV.fetch("OMNISOCIALS_WEBHOOK_SECRET"), tolerance: 300 ) rescue OmniSocials::WebhookVerificationError return head :bad_request end if event["type"] == "post.published" event["data"]["targets"].each do |target| Rails.logger.info "#{target["platform"]} #{target["status"]} #{target["native_post_id"]}" end elsif event["type"] == "post.rejected" Rails.logger.info "Rejected: #{event["data"]["post_id"]} #{event["data"]["approval"]["reason"]}" end head :ok end end

Events: post.scheduled, post.published, post.failed, post.approved and post.rejected. The two approval events carry data.approval with status, decided_by (the approver's user id) and reason (nil on post.approved). To read the full review of a post (steps, approvers, the rejection reason and the comment thread), call client.posts.get_approval(post_id).

Errors

The base class is OmniSocials::Error. OmniSocials::APIError covers HTTP errors with subclasses AuthenticationError (401), PermissionDeniedError (403), NotFoundError (404), ValidationError (400/422), RateLimitError (429, with #retry_after), and ServerError (5xx), plus APIConnectionError and WebhookVerificationError. Each carries status, code, message, and body.

Ruby
begin client.posts.get("does-not-exist") rescue OmniSocials::NotFoundError => e puts "Gone: #{e.code} #{e.message}" rescue OmniSocials::RateLimitError => e puts "Slow down, retry in #{e.retry_after}s" rescue OmniSocials::ValidationError => e puts "Bad request: #{e.body}" rescue OmniSocials::AuthenticationError puts "Check your API key" rescue OmniSocials::APIConnectionError puts "Network problem" rescue OmniSocials::APIError => e puts "API error: #{e.status} #{e.message}" end

Configuration

Ruby
client = OmniSocials::Client.new( api_key: "omsk_live_...", timeout: 60, # seconds max_retries: 5, # retries after the first attempt base_url: "https://api.omnisocials.com/v1" # override for testing )

Notes

  • A fresh connection is used per request; there is nothing to close
  • All responses are plain Hashes with string keys
  • Omitting folder_id/parent_id leaves a value unchanged; passing nil explicitly moves to root/top level
  • Source: github.com/OmniSocials/omnisocials-ruby
Last modified on October 21, 2026
GoJava
On this page
  • Install
  • Authentication
  • Create a post
  • Upload media
  • Analytics
  • Social Inbox
  • Pinterest product tags
  • Verify webhooks
  • Errors
  • Configuration
  • Notes
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby
Ruby