ProductRelease intake
Get releases into Shotsfrom wherever you ship.
Type a release into the form, send it from CI with an API key, or let GitHub, GitLab, or your own pipeline send it through a signed webhook. Every path creates the same release, ready for launch intelligence.
curl https://shots.playbookmedia.io/api/v1/releases \
-H "x-api-key: $SCREENSHOT_STUDIO_API_KEY" \
-H "Idempotency-Key: release-v2.4.0" \
-H "Content-Type: application/json" \
-d '{
"title": "Recurring invoices",
"benefitStatement": "Bill repeat customers without rebuilding the invoice.",
"sourceUrls": [
"https://github.com/acme/billing/pull/452",
"https://acme.com/changelog/recurring-invoices"
]
}'201 Created
{
"created": true,
"release": { "id": "cm…", "status": "DRAFT", "title": "Recurring invoices" }
}Three ways in
Pick the path that fits how you ship:the form, the REST API, or a webhook.
All three create the same release in your workspace.
Release form
Typed by your team.
title · why it matters · links
REST API
From CI with an API key. A retry with the same key returns 200 with the first result.
POST /api/v1/releasesIdempotency-Key
Signed webhook
From GitHub, GitLab, or your own pipeline.
X-Shots-Signature
Release
Recurring invoices
Every path lands in the same release, scoped to your workspace.
Signed webhook, step by step
01Verify the signature
Over the raw body bytes, before anything is parsed.
X-Shots-SignatureX-Shots-Timestamp
GitHub X-Hub-Signature-256 · GitLab webhook-signature
02Parse the event
Read the release from the verified body.
GitHub and GitLab link their release page as a source
03Dedupe the delivery
Redeliveries are recognized, so a retry cannot create a second release.
X-Shots-Event-Id
GitHub X-GitHub-Delivery · GitLab webhook-id
04Release created
One release, ready for launch intelligence.
201 Created
Fenced as untrusted for review
The release form
Name the release, say why it matters, and paste the links. Best when a teammate writes it.The REST API
POST /api/v1/releases with a workspace API key from CI or a deploy script. Retries are safe with an idempotency key.Signed webhooks
Point a GitHub or GitLab release webhook at your source app, or sign your own. GitHub and GitLab releases link their release page as a source.
The release
A release has six fields,and two are enough to start.
A release is what you send, and a launch is built from it. Editing the release later doesn't rewrite launches already built from it.
| Field | Rule |
|---|---|
| title | Required. Up to 160 characters. |
| benefitStatement | Why it matters, up to 500 characters. Optional when a source link is given. |
| description | What changed, in plain text. Up to 10,000 characters. |
| audience | Who should hear about it. Up to 1,000 characters. |
| sourceUrls | Up to 20 public http(s) links: the pull request, changelog, and docs. |
| productSurfaceId | Optional. The product page this release changes. |
Webhooks
Unsigned webhooks are refused,and a redelivery never creates a second release.
Signatures are checked over the exact body bytes before anything is parsed. The table shows the header each sender signs with and the one that guards against replays.
| Sender | Signature | Replay protection |
|---|---|---|
| GitHub | X-Hub-Signature-256 | X-GitHub-Delivery |
| GitLab | webhook-signature | webhook-timestamp |
| Any pipeline | X-Shots-Signature | X-Shots-Timestamp, -Event-Id |
A release that arrives by webhook or API key has no author on your team. The AI treats its text as untrusted and shows it to the reviewer with the sources.
API keys
API keys can create releasesbut can't approve or publish.
Workspace API keys carry one of 8 scopes. They are hashed at rest and shown once, and a revoked key stops working on the next request. No key can manage teammates, SSO, SCIM, audit log export, retention, or publishing.
| Scope | Allows |
|---|---|
| artifact:read | Read releases, assets, and generated artifacts. |
| asset:write | Create and complete workspace assets. |
| draft:write | Create, update, and delete content drafts. |
| onboarding:run | Read a product site into its profile and follow the run. |
| post:schedule | Schedule approved campaign posts. People still approve. |
| release:create | Create releases, the input to every launch. |
| source:write | Register source apps that send signed webhooks. |
| upload:sign | Request signed upload URLs for asset bytes. |
| Endpoint | Scope | Does |
|---|---|---|
| POST /api/v1/releases | release:create | Create a release. Accepts Idempotency-Key. |
| GET /api/v1/releases | artifact:read | List workspace releases. |
| POST /api/v1/source-apps | source:write | Register a source app for webhooks. |
| POST /api/v1/assets/upload-url | upload:sign | Reserve an asset and get a write-once upload URL. |
| POST /api/v1/assets/{assetId}/complete | asset:write | Mark an upload complete. |
| GET /api/v1/assets/{assetId}/download-url | artifact:read | Get a short-lived download URL. |
| DELETE /api/v1/assets/{assetId} | asset:write | Queue deletion of an unused asset. Pro and up. |
Conventions
The API follows the same rules everywhere:safe retries, request IDs, and one error format.
The public OpenAPI spec is generated from the same Zod contracts the routes validate with, and tests keep the two in sync.
Idempotency-KeySafe retries
Up to 128 characters. Longer keys are rejected, not cut short. A replay returns 200 with the first result.X-Request-IdTraceable
Every response carries a request ID that also appears in the audit log./openapi.jsonOpenAPI 3.1
Also at /.well-known/openapi.json, with an interactive reference at /api-reference.Accept: text/markdownReadable by AI tools
llms.txt, llms-full.txt, and Markdown versions of supported pages.
{
"error": "This workspace has used its monthly AI credits.",
"code": "workspace_quota_exceeded",
"message": "This workspace has used its monthly AI credits.",
"hint": "Wait for the next cycle or move to a larger plan.",
"status": 429,
"documentation": "https://shots.playbookmedia.io/api-reference#errors"
}Rate limits
API write limitsfor each plan.
API writes are limited per workspace by plan. Reads are not counted.
| Plan | API writes per minute | AI credits per month |
|---|---|---|
| Free | 0 | 0 |
| Pro | 300 | 3,600 |
| Business | 1,500 | 13,200 |
| Enterprise | 10,000 | 54,000 |
Questions
Anything else? Talk to us.
Is there an SDK?
Does the API send webhooks back to me?
Can the API create launches or approve posts?
Is there a GitHub App?
Related