Veröffentlichen und planen Sie in 13 Netzwerken mit einer REST-API. Lesen Sie Analysen, beantworten Sie Kommentare und DMs und erhalten Sie einen signierten Webhook, sobald ein Beitrag live geht, fehlschlägt oder freigegeben wird.
Authorization: Bearer YOUR_API_KEY {"content":"Our autumn menu lands on Friday.","social_profile_ids":[101,102],"publish_time":"2026-11-13T09:00","timezone":"America/New_York","status":"scheduled"}
{"id":18342,"status":"scheduled","publish_time":"2026-11-13T09:00:00-05:00","timezone":"America/New_York","social_profiles":[{"name":"Northwind Instagram","platform":"instagram","status":"pending"},{"name":"Northwind LinkedIn","platform":"linkedin","status":"pending"}]}
X-RobinReach-Event: post.published X-RobinReach-Signature: t=1794150000,v1=5257a869e7… {"id":"evt_1c626cf6bcb5","type":"post.published","data":{"post":{"id":18342,"status":"published","summary":{"total":2,"published":2,"failed":0}}}}
Ein Beispielaustausch mit erfundenen IDs. Webhooks kommen als signierter POST an Ihrem HTTPS-Endpunkt an.
Senden Sie den Text, die Profile und die Uhrzeit. RobinReach prüft den Beitrag gegen die Regeln jedes Netzwerks, setzt ihn in den Kalender und veröffentlicht ihn pünktlich.
GET /api/v1/social_profiles auf, um die IDs der Konten zu erhalten, auf denen Sie posten möchten.timezone gelesen, 09:00 heißt also 9:00 für Ihr Publikum.Unsicher, ob ein Beitrag durchgeht? POST /api/v1/posts/validate führt dieselben Prüfungen aus, ohne etwas zu speichern.
curl -X POST https://robinreach.com/api/v1/posts \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "Our autumn menu lands on Friday.", "social_profile_ids": [ 101, 102 ], "publish_time": "2026-11-13T09:00", "timezone": "America/New_York", "status": "scheduled" }'
require "net/http" require "json" uri = URI("https://robinreach.com/api/v1/posts") request = Net::HTTP::Post.new(uri, "Authorization" => "Bearer YOUR_API_KEY", "Content-Type" => "application/json") request.body = { content: "Our autumn menu lands on Friday.", social_profile_ids: [101, 102], publish_time: "2026-11-13T09:00", timezone: "America/New_York", status: "scheduled" }.to_json response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(request) } puts response.body
const response = await fetch("https://robinreach.com/api/v1/posts", { method: "POST", headers: { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ content: "Our autumn menu lands on Friday.", social_profile_ids: [101, 102], publish_time: "2026-11-13T09:00", timezone: "America/New_York", status: "scheduled", }), }); console.log(await response.json());
import requests response = requests.post( "https://robinreach.com/api/v1/posts", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={ "content": "Our autumn menu lands on Friday.", "social_profile_ids": [101, 102], "publish_time": "2026-11-13T09:00", "timezone": "America/New_York", "status": "scheduled", }, timeout=30, ) print(response.json())
Die API deckt die Arbeit ab, die Ihr Team im Dashboard erledigt, damit Ihr Code sie auch erledigen kann.
Beiträge erstellen, prüfen, sofort veröffentlichen, umplanen und löschen, mit den eigenen Optionen jedes Netzwerks.
/posts/posts/validate/posts/{id}/posts/{id}/publish_now/posts/{id}/rescheduleBilder, Videos und PDFs hochladen, in Ordnern ordnen und in Beiträgen wiederverwenden.
/attachments/attachments/{id}/folders/folders/{id}Marken und verbundene Profile auflisten, dazu Pinterest-Pinnwände, Instagram-Audio, WordPress-Kategorien und -Schlagwörter, Standorte und Hashtag-Gruppen.
/brands/brands/{id}/social_profiles/social_profiles/{id}/social_profiles/{id}/pinterest_boards/locations/hashtag_groupsInteraktionen pro Profil und pro Beitrag, Ihre Top-Beiträge, diese Woche im Vergleich zur letzten und der Kalender.
/analytics/summary/analytics/top_posts/posts/{id}/analytics/social_profiles/{id}/analytics/calendarKommentarverläufe, Facebook- und Instagram-DMs und Google-Rezensionen aller Profile lesen und als Marke antworten.
/comment_threads/comment_threads/{id}/replyComment-to-DM-Automatisierungen, RSS-Feeds und Repurposing-Aufgaben erstellen, pausieren und fortsetzen. Einen Feed vor dem Hinzufügen prüfen und eine Aufgabe bei Bedarf sofort ausführen.
/comment_automations/comment_automations/{id}/pause/rss_feeds/rss_feeds/validate/rss_feeds/{id}/sync/repurposing_tasks/repurposing_tasks/{id}/runDie Bio-Seite der Marke und ihre Blöcke bearbeiten, sie anordnen, die Analysen der Seite lesen und ihren QR-Code abrufen.
/bio_page/bio_page/blocks/bio_page/blocks/{id}/bio_page/blocks/reorder/bio_page/analytics/bio_page/qrMit Connect Links fügen Kunden ihre eigenen Konten hinzu. Mit Approval Links prüfen sie Beiträge, ohne sich anzumelden.
/connect_links/connect_links/{id}/approval_links/approval_links/{id}Endpunkte hinzufügen, Testereignisse senden, Signaturschlüssel erneuern und das Zustellprotokoll lesen.
/webhook_endpoints/webhook_endpoints/{id}/webhook_endpoints/{id}/test/webhook_endpoints/{id}/rotate_secret/webhook_endpoints/{id}/enable/webhook_endpoints/{id}/deliveriesFügen Sie einen HTTPS-Endpunkt hinzu, und RobinReach sendet für die gewählten Ereignisse einen signierten POST. Alarmieren Sie Ihr Team, synchronisieren Sie Ihr CRM oder beantworten Sie einen Kommentar oder eine DM in der Sekunde, in der sie eintreffen.
post.publishedEin Beitrag ging auf jedem ausgewählten Profil raus.post.partially_publishedEin Beitrag ging auf einigen Profilen raus und schlug auf anderen fehl.post.failedEin Beitrag schlug auf jedem ausgewählten Profil fehl, jeweils mit dem Grund.post.approvedEin Beitrag wurde im Dashboard oder über einen Approval Link freigegeben.post.rejectedEin Beitrag wurde abgelehnt, mit der Notiz der prüfenden Person.comment.receivedJemand anderes hat auf einem verbundenen Profil kommentiert. Ihre eigenen Antworten lösen es nie aus.review.receivedEine neue Rezension im Google Unternehmensprofil ist eingegangen.message.receivedJemand hat einer verbundenen Facebook-Seite oder einem Instagram-Konto eine Direktnachricht geschickt.Bis zu 10 Endpunkte pro Marke. Mit dem Master-Schlüssel kann ein Endpunkt auf Ihrer Standardmarke alle Marken gleichzeitig empfangen.
{
"id": "evt_1c626cf6bcb54613a8053e24d5361527",
"type": "post.published",
"created_at": "2026-11-13T14:00:00Z",
"api_version": "2026-11-01",
"data": {
"brand": {
"id": "northwind",
"name": "Northwind Coffee"
},
"post": {
"id": 18342,
"status": "published",
"content": "Our autumn menu lands on Friday.",
"social_profiles": [
{
"id": 101,
"platform": "instagram",
"status": "published",
"remote_url": "https://www.instagram.com/p/C9xYz12AbCd/"
},
{
"id": 102,
"platform": "linkedin",
"status": "published",
"remote_url": "https://www.linkedin.com/feed/update/urn:li:share:7392018841650188288/"
}
],
"summary": {
"total": 2,
"published": 2,
"failed": 0
}
}
}
}
Jede Anfrage trägt X-RobinReach-Signature: t=…,v1=…, einen HMAC-SHA256 aus Zeitstempel und Rohdaten, signiert mit dem Signaturschlüssel Ihres Endpunkts. Prüfen Sie ihn, bevor Sie den Daten vertrauen, und lehnen Sie Zeitstempel ab, die älter als fünf Minuten sind.
class RobinreachWebhooksController < ActionController::API def create body = request.raw_post return head :unauthorized unless valid_signature?(body, request.headers["X-RobinReach-Signature"]) event = JSON.parse(body) # Skip event["id"] if you have seen it, then queue the work. head :ok end private def valid_signature?(body, header, tolerance: 300) parts = header.to_s.split(",").map { |p| p.split("=", 2) }.select { |kv| kv.size == 2 }.to_h t = Integer(parts["t"].to_s, exception: false) return false unless t && parts["v1"] && (Time.now.to_i - t).abs <= tolerance expected = OpenSSL::HMAC.hexdigest("SHA256", ENV.fetch("ROBINREACH_WEBHOOK_SECRET"), "#{t}.#{body}") ActiveSupport::SecurityUtils.secure_compare(expected, parts["v1"]) end end
import crypto from "node:crypto"; import express from "express"; const app = express(); app.post("/webhooks/robinreach", express.raw({ type: "application/json" }), (req, res) => { const raw = req.body.toString("utf8"); if (!verify(raw, req.get("X-RobinReach-Signature"), process.env.ROBINREACH_WEBHOOK_SECRET)) { return res.sendStatus(401); } const event = JSON.parse(raw); // Skip event.id if you have seen it, then queue the work. res.sendStatus(200); }); function verify(rawBody, header, secret, toleranceSec = 300) { const parts = Object.fromEntries((header || "").split(",").map((p) => p.split("=", 2))); const t = Number(parts.t); if (!t || !parts.v1 || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"); const a = Buffer.from(expected), b = Buffer.from(parts.v1); return a.length === b.length && crypto.timingSafeEqual(a, b); }
import hashlib, hmac, os, time from flask import Flask, request, abort app = Flask(__name__) @app.post("/webhooks/robinreach") def robinreach_webhook(): raw = request.get_data() if not verify(raw, request.headers.get("X-RobinReach-Signature", ""), os.environ["ROBINREACH_WEBHOOK_SECRET"]): abort(401) event = request.get_json() # Skip event["id"] if you have seen it, then queue the work. return "", 200 def verify(raw_body, header, secret, tolerance=300): parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p) try: t = int(parts["t"]) except (KeyError, ValueError): return False if "v1" not in parts or abs(time.time() - t) > tolerance: return False expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, parts["v1"])
Eine fehlgeschlagene Zustellung wird 7 Mal über etwa 28 Stunden wiederholt, mit jedes Mal größeren Abständen.
Nach 10 fehlgeschlagenen Zustellungen in Folge pausiert der Endpunkt, und der Marken-Admin bekommt eine E-Mail. Mit einem Klick geht es weiter.
Jedes Ereignis hat eine eindeutige ID, damit Ihr Code das seltene Duplikat ignorieren kann.
Jeder Versuch, Statuscode und Antworttext wird 30 Tage aufbewahrt, und Sie können jederzeit ein Testereignis senden.
https://robinreach.com/api/v1. Jeder Pfad auf dieser Seite ist relativ dazu.Authorization: Bearer YOUR_API_KEY. Ein Abfrageparameter api_key funktioniert auch, kann aber in Serverprotokollen landen, nutzen Sie also lieber den Header.brand_id. Ein Markenschlüssel erreicht nur eine Marke und kann daher bedenkenlos an Kunden oder ein Tool mit nur einer Aufgabe gehen.America/New_York, oder in der Zeitzone der Marke, wenn Sie keine angeben.401 bei fehlendem oder falschem Schlüssel, 404 für alles außerhalb der Reichweite des Schlüssels, 422 mit klarer Meldung, wenn ein Beitrag gegen die Regeln eines Netzwerks verstößt.429 mit den Headern Retry-After und X-RateLimit-*, damit Ihr Client selbst zurückfahren kann./api/v1, und jeder Webhook nennt die Version seiner Daten in api_version.Jedes Netzwerk behält seine eigenen Optionen, etwa Instagram-Reels, YouTube-Titel, Pinterest-Pinnwände oder LinkedIn-Dokumentbeiträge, pro Beitrag in platform_options gesetzt.
Geben Sie Ihren Nutzern Veröffentlichung in 13 Netzwerken, ohne die API jedes Netzwerks selbst bauen und pflegen zu müssen.
Führen Sie jede Kundenmarke aus einem Konto, mit einem Markenschlüssel und eigenen Webhooks für jeden Kunden.
Machen Sie aus neuen Produkten, Inseraten, Artikeln oder Events geplante Beiträge, sobald es sie gibt.
Fehlgeschlagene Beiträge an Slack senden, Ergebnisse in Ihr CRM schieben und Analysen in Ihre eigenen Dashboards holen.
Claude, ChatGPT, Cursor und Ihre eigenen Agenten erhalten dieselben Aktionen als Tools, über eine URL und denselben Schlüssel.
Zum MCP-ServerInstallieren Sie n8n-nodes-robinreach und planen Sie Beiträge aus jedem n8n-Workflow.
Auf GitHub ansehenRufen Sie die API aus einem Webhook-Schritt in Zapier oder einem HTTP-Modul in Make auf. Die Seite Integrationen hat die Einstellungen zum Kopieren bereit.
Integrationen öffnenAuthorization: Bearer YOUR_API_KEY. Ein Abfrageparameter api_key funktioniert auch, aber der Header hält den Schlüssel aus Serverprotokollen heraus.brand_id. Jede Marke kann außerdem einen eigenen Markenschlüssel haben, der nur für diese Marke gilt: Er braucht keine brand_id, sieht Ihre anderen Marken nicht und kann keine Marken anlegen oder löschen.POST /api/v1/posts mit content, den social_profile_ids, einer publish_time in ISO 8601, einer timezone wie America/New_York und status auf scheduled. Rufen Sie vorher POST /api/v1/posts/validate auf, um ihn gegen die Regeln jedes Netzwerks zu prüfen, ohne ihn zu speichern.t und v1 aus dem Header X-RobinReach-Signature, berechnen Sie einen HMAC-SHA256 von t.raw_body mit Ihrem Signaturschlüssel und vergleichen Sie beide in konstanter Zeit. Lehnen Sie Zeitstempel ab, die älter als fünf Minuten sind. Die Beispiele oben zeigen es in Ruby, Node und Python.GET /api/v1/comment_threads listet Kommentarverläufe, Facebook- und Instagram-Unterhaltungen und Google-Rezensionen auf, und POST /api/v1/comment_threads/{id}/reply beantwortet einen davon als Marke: unter dem Kommentar, privat bei einer DM oder öffentlich auf Google bei einer Rezension. Kombinieren Sie es mit den Webhooks comment.received und message.received, um zu antworten, sobald etwas eintrifft.Schlüssel erzeugen, einen Beitrag mit einer Anfrage planen und einen Webhook hinzufügen. Die Referenz enthält jedes Feld.
API-Zugriff ist in Bloom, Thrive und Scale enthalten.