REFERENCE

Refrain API

A JSON API over HTTPS. Every endpoint lives under api.refrain.dev/v1, every response is JSON, and every request needs a key. The sections below run in the order you will need them.

Introduction

A project is the unit everything hangs off. Keys, pipelines, webhooks and usage are all scoped to one, and an organisation can hold as many as it needs. Nothing you do in one project is visible from another.

Versions move forward, never sideways. A v1 endpoint keeps its shape until the major version changes, and breaking changes are announced in the changelog with a removal date before they land.

Authentication

Added in v2.2.0

Creating a key

Open the project, go to Settings, then API keys. A key is shown once when it is created and never again, so store it before you close the dialog.

Sending the key

Send the key in the Authorization header as a bearer token. Keys sent in a query string are rejected, because query strings end up in server logs.

GET /v1/projects

curl

curl https://api.refrain.dev/v1/projects \

-H "Authorization: Bearer $REFRAIN_KEY"

{ "data": [ { "id": "prj_31a", "name": "Acme" } ] }

BREAKING IN v3

The X-Api-Token header is accepted until v3.0.0 and removed after it. Move to Authorization: Bearer before you upgrade.

Rotating without downtime

Create the replacement key first, deploy it, then revoke the old one. Two keys can be active at once, so there is no window where requests fail.

Your first request

List the projects the key can see. The response carries a data array and a cursor, and the cursor is null when there is nothing left to page through.

GET /v1/projects

curl

curl https://api.refrain.dev/v1/projects \

-H "Authorization: Bearer $REFRAIN_KEY"

{ "data": [ { "id": "prj_31a", "name": "Acme" } ], "cursor": null }

Changed in v2.2.1

Every list endpoint is cursor based. Pass the cursor from the previous response as the starting_after parameter, and stop when the response returns a null cursor. Cursors are anchored to a monotonic sequence rather than an offset, so a record deleted mid-pagination cannot cause a row to be skipped.

Page size defaults to 50 and caps at 200. A batch write accepts up to 500 rows, and anything above that returns 413 with the accepted maximum in the body.

GET /v1/events

curl

curl "https://api.refrain.dev/v1/events?limit=50" \

-H "Authorization: Bearer $REFRAIN_KEY"

{ "data": [ ... ], "cursor": "evt_9f21c4" }

Rate limits

Limits are per project, not per key, so rotating a key does not reset a limit. Every response carries the remaining quota and the reset time in headers.

A batch of rows costs one unit of quota rather than one per row. When you exceed the limit the API returns 429 with a Retry-After header, and retrying before that time does not extend the block.

Webhooks

Register an endpoint per project and choose the events it receives. Deliveries are signed, retried on a backoff for 24 hours, and recorded for 90 days so you can see what was sent and what came back.

Verify the signature before you trust the body. Compare the timestamp and payload against the header using a constant time comparison, and reject anything older than five minutes.

POST /your-endpoint

node

const sig = req.headers["refrain-signature"]

const body = req.rawBody

if (!verify(sig, body, process.env.WEBHOOK_SECRET)) return res.status(400).end()

Errors

Errors return a status code, a stable machine readable code, and a message written for a person. The code is the part to branch on. The message is the part to log.

400 invalid request. 401 missing or bad key. 403 the key is valid but scoped elsewhere. 404 no such record. 413 the batch is too large. 429 rate limited. 500 our fault, and safe to retry.

Migrating to v3

v3 removes the X-Api-Token header. Send the key as Authorization: Bearer instead. Both headers are accepted until v3.0.0 and requests still using the old one return a Deprecation header carrying the removal date.

Nothing else in the request or response shape changes. If your client already sends the bearer header, there is no work to do.

Landing, docs, changelog, pricing.

Ready to ship the docs?

pages

8

cms collections

2

breakpoints

3

code files

1

licence

unlimited

Refrain

The site your product needs after it ships.

© 2026 Refrain

All product data on this site is demo data.

A Framer template

Demo product

v2.4.0

· released

Buy this template

Create a free website with Framer, the website builder loved by startups, designers and agencies.