Ruby Quick Start
Ruby syntax for the five Core Workflows. The canonical page owns the API semantics.
Client
require 'json'
require 'net/http'
require 'securerandom'
require 'time'
require 'uri'
BASE_URL = 'https://api.publora.com/api/v1'
def publora(method, path, body: nil, idempotency_key: nil)
uri = URI("#{BASE_URL}/#{path}")
request = Net::HTTP.const_get(method.capitalize).new(uri)
request['x-publora-key'] = ENV.fetch('PUBLORA_API_KEY')
request['Content-Type'] = 'application/json'
request['Idempotency-Key'] = idempotency_key if idempotency_key
request.body = JSON.generate(body) if body
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
raise "Publora returned #{response.code}" unless response.is_a?(Net::HTTPSuccess)
JSON.parse(response.body)
end
platform_id = ENV.fetch('PUBLORA_PLATFORM_ID')1. Draft
draft = publora('post', 'create-post', body: {
content: 'Draft from Ruby', platforms: [platform_id]
})No scheduledTime means draft.
2. One-shot schedule
scheduled = publora('post', 'create-post', idempotency_key: SecureRandom.uuid, body: {
content: 'Scheduled from Ruby',
platforms: [platform_id],
scheduledTime: (Time.now.utc + 300).iso8601
})3. Upload and schedule
Follow the canonical presigned sequence. PUT bytes to the returned storage URL without the Publora API header, then:
upload_uri = URI(upload_url)
upload_request = Net::HTTP::Put.new(upload_uri)
upload_request['Content-Type'] = 'image/jpeg'
upload_request.body = File.binread('photo.jpg')
upload_response = Net::HTTP.start(upload_uri.host, upload_uri.port, use_ssl: true) do |http|
http.request(upload_request)
end
raise 'Storage upload failed' unless upload_response.is_a?(Net::HTTPSuccess)
publora('post', "complete-media/#{media_file_id}")
publora('put', "update-post/#{post_group_id}",
idempotency_key: "schedule-#{post_group_id}", body: {
status: 'scheduled', scheduledTime: (Time.now.utc + 300).iso8601
})4. Update
publora('put', "update-post/#{post_group_id}",
idempotency_key: "reschedule-#{post_group_id}", body: {
status: 'scheduled', scheduledTime: (Time.now.utc + 600).iso8601
})5. Webhook consumer
require 'openssl'
post '/publora-webhook' do
raw = request.body.read
expected = OpenSSL::HMAC.hexdigest('SHA256', ENV.fetch('PUBLORA_WEBHOOK_SECRET'), raw)
halt 401 unless Rack::Utils.secure_compare(expected, request.env['HTTP_X_PUBLORA_SIGNATURE'].to_s)
envelope = JSON.parse(raw)
status 204
endRails/Faraday/HTTParty may wrap the same calls; they do not change the wire contract. CSV import, batch operations, and LinkedIn analytics remain discoverable through dedicated pages and the OpenAPI document. See Webhooks.