ProductRelease intake
Releases in.From anywhere you ship.
Type a release into the form, send it from CI with an API key, or let GitHub, GitLab, or your own pipeline deliver it through a signed webhook. Every path lands in the same release, ready for launch intelligence.
curl https://www.screenshot-studio.com/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
A form, an API,or a webhook.
Pick the path that fits how you ship. All three create the same release object, scoped to your workspace.
The release form
Name the release, say why it matters, and paste the links. Best when a person is writing the brief.The REST API
POST /api/v1/releases with an organization 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
Six fields.Two are enough.
A release is a brief, not a campaign. Editing it later never rewrites the campaigns 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 screen this release changes. |
Webhooks
Signed or refused.Deduplicated by default.
Signatures are checked over the exact body bytes before anything is parsed. Redeliveries are deduplicated, so a retried webhook creates one release.
| Sender | Signature | Replay protection |
|---|---|---|
| GitHub | X-Hub-Signature-256 | X-GitHub-Delivery |
| GitLab | webhook-signature | webhook-timestamp |
| Any pipeline | X-Screenshot-Studio-Signature | X-Screenshot-Studio-Timestamp, -Event-Id |
A release that arrives by webhook or API key has no author on your team, so launch intelligence fences its brief as untrusted and shows it to the reviewer with the sources.
API keys
Narrow keys.Nothing to approve with.
Organization API keys carry one of 5 scopes. They are hashed at rest, shown once, and revoked on the next request. No key can manage members, SSO, SCIM, audit drains, retention, or publishing, and no key can approve.
| Scope | Allows |
|---|---|
| artifact:read | Read releases, assets, and generated artifacts. |
| asset:write | Create and complete workspace assets. |
| 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
Predictable by design.Boring on purpose.
The public spec is generated from the same Zod contracts the routes validate with, and tests keep the two from drifting.
Idempotency-KeySafe retries
Up to 128 characters. Longer keys are rejected, never truncated. 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 a live Scalar reference at /api-reference.Accept: text/markdownAgent friendly
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://www.screenshot-studio.com/api-reference#errors"
}Rate limits
Writes per minute,by plan.
API writes are limited per workspace by plan. Reads are not counted.
| Plan | API writes per minute | AI credits per month |
|---|---|---|
| Free | 30 | 250 |
| 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 campaigns or approve posts?
Is there a GitHub App?
Related