Shipnoted

Docs

REST API

Everything in the dashboard, from your own code. JSON in, JSON out, bearer keys with scopes.

Authentication#

On Pro and Team, create a key under Install & connect → API keys. It starts with snk_ and is shown once. Send it as a bearer token:

curl -H "Authorization: Bearer $SHIPNOTED_API_KEY" https://shipnoted.com/api/v1/your-slug/releases

Not sure of the slug? GET /api/v1/projects lists the projects a key can use, and GET /api/v1/your-slug/project checks a key and slug in one call.

Scopes#

A key can be limited to what its job needs, to one project, and to a lifetime. A key for CI cannot read your subscribers’ email addresses; a key for a support tool cannot publish a release. Keys made before scopes existed keep full access.

readReleases, requests, themes, the loop and project details
feedback:writePost requests, move their status, reply
releases:writeDraft, edit, publish and delete releases
subscribers:readThe list of people subscribed (email addresses)
webhooks:writeCreate, change and delete webhook endpoints

The presets in the dashboard: Full access; CI: read and publish releases; Support tools: read and write requests; Read only. Use Pick scopes for anything else, tick Only for this project to confine a key to one, and choose an expiry for short-lived access.

Errors and limits#

Failures always look the same, whatever the endpoint: { "ok": false, "error": "What went wrong, in words" } with a meaningful status (400, 401, 402, 403, 404, 409, 429; see the list). Each key can make 120 requests a minute; past that you get a 429 with a Retry-After header.

Paging#

List endpoints take limit and offset. They answer with hasMore (or total) so you know when to stop.

let offset = 0
for (;;) {
  const { feedback, hasMore } = await sn.feedback.list({ status: "open", limit: 100, offset })
  for (const f of feedback) console.log(f.ref, f.title)
  if (!hasMore) break
  offset += 100
}

Retrying safely#

Filing a request from a support tool is the call most likely to be retried. Send an idempotencyKey (a ticket id works) and a repeat is recognised: you get the first request’s reference back with duplicate: true and nothing new is filed.

curl -X POST https://shipnoted.com/api/v1/your-slug/feedback \
  -H "Authorization: Bearer $SHIPNOTED_API_KEY" -H "content-type: application/json" \
  -d '{"title":"Export to CSV","email":"ada@acme.com","source":"Support","idempotencyKey":"ticket-8841"}'

Publishing is safe to retry too: publishing a release that is already published answers 409 and never emails anyone twice.

OpenAPI#

The whole API as an OpenAPI 3.1 document, no key needed: https://shipnoted.com/api/v1/openapi.json. Feed it to a code generator, import it into Postman or Insomnia, or hand it to an agent. The reference is generated from the same source, so they cannot disagree.