Product
Everything between writing a post and knowing where it landed
A composer that shows each platform’s version, a calendar that understands time zones, reviews before anything goes out, and a delivery record for every destination — in the console for people, and in the same public API for software.

Composer
One post, previewed the way each platform will receive it
Write one post — text, a title, a link, tags and media — and choose where it goes. The preview shows the version each destination will get, produced by the same projection the publisher uses, so a preview and a published post cannot disagree.
Nothing is written by a preview: no post, no delivery, no queued job. Uploaded media is checked in full; media given as a URL is checked when the post publishes, and the preview says which items it could not verify.
- Text trimmed at a word boundary to each platform’s limit, with a warning for every change
- Media a platform refuses is dropped and named, with its position in your list
- Per-platform overrides for the fields only one platform has
- Strict validation, when a post must go out exactly as written or not at all

Scheduling
Drafts, schedules and a calendar that knows what 9 AM means
Every instant is stored in UTC. An organisation has a time zone and a person may have their own, and a schedule can be sent as an exact instant or as a wall-clock time in a named zone — which is what a person means by “Tuesday at nine”.
Twice a year a wall clock is not a number. A time that does not exist when the clocks go forward, or happens twice when they go back, is resolved one documented way, and the response carries a notice saying what was chosen.
- Drafts are stored and not queued until they are released
- Move, duplicate or release a draft or a scheduled post
- The calendar returns what is still to happen, in whole local days
- A post found long after its scheduled time is cancelled and reported, not published late

Approvals
Someone signs off before anything reaches an audience
A post is submitted for review, and a reviewer approves it, sends it back to its author with the changes that are needed, or rejects it. While it waits, it cannot be published — that refusal is the whole point of a review.
Every round stays on the post: who asked, who answered and what they said. A rejected post that should live again is duplicated, so the rejection stays in the record.
- Submit, approve, request changes, reject
- Requesting changes returns the post to draft
- The full review history, per post
Approvals depend on the plan.

Analytics
What went out, where it failed, and what each platform accepts
Delivery outcomes are aggregated per period, per platform and over time, in your time zone. Where a platform reports engagement for a published post, the post’s metrics are read back per delivery and totalled.
A success rate is calculated only over deliveries that have settled, and is shown as nothing rather than zero when nothing has. Empty days are filled in, so a quiet day is never drawn as a straight line through an outage.
- A summary for any period
- Success rate per platform
- Deliveries over time, by outcome
- Per-post metrics where the platform provides them
Analytics depend on the plan.

Media
Upload once, publish everywhere from the same file
Upload images and video once and use them across posts, or give a public URL that is fetched when the post publishes. Every platform in a fan-out reads the same stored file, rather than each one fetching it again.
- Files are identified by their contents against an allow-list — never by extension or the type a client claims
- URLs are fetched only from public addresses, and every redirect is checked
- Width, height and duration are read from the file, so each platform’s rules can be applied
- Alt text travels with each image in the post
In the API
The same capability, for your own code. Each links to its reference entry.
Templates
Start next week’s post from this week’s
Save the posts your team writes on a rhythm — a release note, an event reminder, a weekly round-up — and start the next one from the template instead of a blank composer.
- Reusable content presets, listed, saved, edited and deleted over the API
- The same neutral content a post carries, so a template previews like any post
Templates depend on the plan.
In the API
The same capability, for your own code. Each links to its reference entry.
Connections
Authorise an account once. Then only the API.
Each account is connected once — through the platform’s OAuth sign-in in a browser, or with the token, app password or webhook URL that platform uses. After that, your systems talk only to the relay.
When the person who owns the account is not you, send them a hosted connect link. They connect their own account without an API key or a console login, and the link expires once used or after a short time.
- Tokens encrypted at rest and renewed where the platform allows it
- A connection that stops working is flagged once, and you are told to reconnect
- Check a connection’s credentials on demand
- One authorisation can bring several destinations, such as every Page a person manages

Your own platform apps
Bring your own platform app credentials
By default, connections go through Rutba Relay’s own registered app on each platform. An organisation can register its own app instead — its client credentials, stored encrypted — and OAuth connections to that platform use it from then on.
- For when a platform has approved your app rather than ours
- For publishing under your own brand, with your own app named on the consent screen
- Rotate, relabel or switch off an app without deleting anything
- Federated platforms that register an app per instance at connection time need none
Your own platform apps depend on the plan.
In the API
The same capability, for your own code. Each links to its reference entry.
Webhooks
Signed events when a post, or a delivery, settles
Register an endpoint and choose its events. Each event is signed with HMAC-SHA256 over its timestamp and body, so a receiver can check it came from the relay and refuse a replayed one.
- post.published, post.partial and post.failed, when a post settles
- delivery.succeeded and delivery.failed, per destination
- connection.reauth_required and connection.revoked, when an account needs attention
- A test event, a delivery log and secret rotation for every endpoint
Webhooks depend on the plan.

Idempotency and retries
A retry is one destination, and never a second post
Deliveries, not posts, are the unit of work. A delivery that fails for a transient reason is retried with backoff on its own; one the platform refused is not retried at all, because the same content would be refused the same way.
An Idempotency-Key on a request makes a repeat of it return the original response, so a client that times out and tries again does not publish twice.
- Idempotency keys remembered for 24 hours
- Retry one delivery, or every failed delivery of a post
- A platform’s own rate limit is respected, and publishing to each account is paced below the platform’s ceiling
- A delivery that may have landed but cannot be confirmed is reported, not retried into a duplicate
In the API
The same capability, for your own code. Each links to its reference entry.

One error vocabulary
Every platform fails differently. Your code only needs one handler.
Each platform’s refusals map onto the same codes, and the code decides what happens next — retry, reconnect, or change the content. The full list is on the developers page.
- rate_limited
- Slow down; retried with backoff
- auth_expired
- The token lapsed; renewed where possible, otherwise reconnect
- content_rejected
- The platform refused the post; not retried
- media_rejected
- An attachment was refused; not retried
See it with your own accounts
Create a Rutba account, connect an account on an open platform, and preview a post on every destination before you publish anything.