Subi has a public REST API for reading and changing subscriptions, and webhooks that tell your own system when a subscription changes. Both use plain JSON and come with the Starter, Subi and Subi Plus plans. This page is the short version; the two references hold every field.

Your first call

On Starter, Subi or Subi Plus, create a key in the Subi app under Settings, then API keys. Send it in the X-Api-Key header. Paths end with a slash.

curl "https://api.subi.co/public/v1.0/subscription-contracts/?limit=5" \
  -H "X-Api-Key: $SUBI_API_KEY"

The answer is a page of results with count, next, previous and results. A list returns 15 items unless you pass limit, up to 100, and offset moves through the rest.

Keep the key in an environment variable or your host's secret store. Do not paste it into a chat or commit it.

Keys, plans and limits

What the API does

What it does not do: create or delete a contract, or write to a subscriber. The API has no routes for those.

Webhooks

On Starter, Subi or Subi Plus, register an endpoint for a topic in the app under Settings, then Webhooks. Each topic can have up to five endpoints. Subi sends an HTTP POST with a JSON body when the event happens.

The Test button in the app sends a WEBHOOK_TEST event so you can check your endpoint before real events arrive.

Every delivery carries X-Subi-Topic, X-Subi-Event-Id, X-Subi-Triggered-At and X-Subi-Hmac-Sha256. The last one is the base64 HMAC-SHA256 of the raw body, made with your shop's HMAC secret from the webhook settings in the app. Check it before you trust the body:

const crypto = require("crypto");

function verify(rawBody, secret, header) {
  const expected = crypto.createHmac("sha256", secret)
    .update(rawBody, "utf8").digest("base64");
  const a = Buffer.from(expected), b = Buffer.from(header);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Answer with a 2xx within 10 seconds. A failed delivery is retried up to five times, the first retry after five minutes and each wait doubling. Use X-Subi-Event-Id to skip an event you have already handled.

The references

Stuck on a call? Write to [email protected] with the request you sent and the answer you got, and leave the key out.