Docs · Automate

API and webhooks

API keys, what they can do, signed webhooks when posts go out, and Zapier and Make recipes.

Razzle has a small HTTP API and outgoing webhooks. Use them to make drafts from another tool, or to hear when a post goes out or gets approved. They're the same pieces Razzle's MCP server for AI agents uses, so anything an agent can do, a script, Zapier or Make can do too.

API keys

Open Settings → AI agents and make a key. It starts with rzl_ and is shown once, so copy it somewhere safe. Send it with every request:

Authorization: Bearer rzl_…

A key acts as you, on your projects, uploads, videos and carousels only. It can't change your account, billing or team, and it never posts: a person approves every post and presses Schedule all in the Calendar. Remove a key in Settings → AI agents and it stops working at once. Resetting your password or signing out of other devices ends every key.

Requests go to https://getrazzle.com. A team's keys share the agent limits: 60 requests a minute, and up to 50 new drafts a day on Free or 250 on Pro (UTC days; edits don't count). A request over a limit gets an error that says so: wait, don't retry in a loop.

What a key can do

RouteWhat it's for
GET /api/projects, POST /api/projectsList your projects, or make one.
GET /api/projects/{id}/foldersA project's folders.
GET /api/media, POST /api/mediaList a project's clips and photos, or start an upload.
GET /api/media/{id}, POST /api/media/{id}/completeOne file, and finishing its upload.
GET /api/items, POST /api/itemsList videos and carousels, or make a draft (kind: video or carousel).
POST /api/items/{id}/editChange a draft's words, music, look or slides.
POST /api/items/{id}/seriesAdd a draft to a numbered series.
GET /api/musicThe music library, to pick a track by id.
GET /api/posts/readyApproved posts waiting for a time.
POST /api/posts/proposePropose times for approved posts. Nothing posts until a person presses Schedule all.

The agent reference lists every option these take (templates, styles, script directives, palettes, fonts, limits), since the MCP tools pass them straight through. The quickest draft is a carousel from words:

curl https://getrazzle.com/api/items \
  -H "Authorization: Bearer $RAZZLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"carousel","projectId":"…","script":"Three things we learned\nfrom 100 launches\n\nShip on Tuesdays\n\nFollow for more"}'

The reply has the new draft's id. Open it in Razzle to check it, change anything and post. Leave out projectId to use your most recent project.

Webhooks

An admin adds one https address in Team → Plan → Webhook. Razzle then sends a JSON POST there for each of these events:

  • post.posted: a post went out (or went out to some of its accounts). data has postId, itemId, title, projectId, status (posted or partial) and results, one per account with its status, the live url and any error.
  • post.failed: a post couldn't go out. Same fields, with status failed.
  • item.approved: someone approved a video or carousel. data has itemId, title, kind, projectId and by, the approver's name.

Every body looks like {"event": "post.posted", "at": "2026-11-10T09:30:00.000Z", "team": "…", "data": {…}}. The X-Razzle-Event header names the event. Razzle sends each event once, with an eight-second timeout. A webhook that fails never affects the post, so make your end quick and reply with any 2xx.

Check the signature

The X-Razzle-Signature header is sha256= plus the hex HMAC-SHA256 of the raw body, keyed with the secret shown next to your webhook (whsec_…). Check it before trusting the body. In Node:

import { createHmac, timingSafeEqual } from "node:crypto";

function fromRazzle(rawBody, header, secret) {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  return !!header && header.length === expected.length && timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}

Use the body exactly as it arrived, before any JSON parsing. Parsing and re-encoding it changes the bytes and the signature won't match.

Zapier

To act when a post goes live (log it in a sheet, tell Slack, email a client):

  1. In Zapier, make a Zap with the trigger Webhooks by Zapier → Catch Hook, and copy the address it gives you.
  2. Paste it into Team → Plan → Webhook in Razzle.
  3. Approve and post something, or wait for the next scheduled post, so Zapier sees a sample.
  4. Add a Filter step that continues only when event is post.posted, then add your actions. data.results[0].url is the live post's link.

Zapier's catch hook doesn't check the signature. If that matters, point the webhook at your own endpoint and check it there.

Make

To turn rows, form answers or new products into Razzle drafts:

  1. In Make, add an HTTP → Make a request module after your trigger (Google Sheets, Typeform, Airtable…).
  2. URL https://getrazzle.com/api/items, method POST, a header Authorization with Bearer and your key, body type raw, content type JSON.
  3. Body: {"kind": "carousel", "projectId": "…", "script": "…"}, with the script built from your trigger's fields. One slide per paragraph, so separate slides with a blank line.

Each run makes a draft in Razzle for you to review and post. For the other way round, Make's Webhooks → Custom webhook trigger works like Zapier's catch hook above.

Shops

Shopify and WooCommerce don't need the API: a project's Settings → Shop integrations (admins) turns new products and price drops into drafts on its own. See getting started.

Updated