Authentication

Bearer tokens for the REST API.

Every call to api/v1 carries one header — Authorization: Bearer pkd_…. No signing, no nonces, no clock skew to worry about. HTTPS handles the transport.

Token shape

onpack tokens begin with pkd_ followed by 32 random hex bytes. They are opaque — don't try to parse them. Tokens are account-level: one token authorises calls against every brand your company owns. Scope is enforced by the :brand_slug path segment in the URL.

Sending the token

curl
curl https://onpack.io/api/v1/brands/milka/scans \
  -H "Authorization: Bearer pkd_••••••••••••••••"
Ruby
require "net/http"
uri = URI("https://onpack.io/api/v1/brands/milka/scans")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['ONPACK_API_TOKEN']}"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
Node
const res = await fetch("https://onpack.io/api/v1/brands/milka/scans", {
  headers: { Authorization: `Bearer ${process.env.ONPACK_API_TOKEN}` }
});

Responses you should expect

StatusMeaning
200 OKRequest succeeded. Body is JSON.
401Missing or invalid token.
402Billing inactive for your company. Re-activate from the dashboard.
404Resource not found or belongs to a brand outside your company.
422Validation failed. Details in details.

Rotating a token

Rotate any time from the dashboard. Clicking Regenerate invalidates the old token immediately — there is no overlap window, so plan a deploy to your services first.

!
Only company managers can generate or rotate tokens. If you can't see the API page, ask a teammate with the right role to invite you.

Scope: what one token can reach

A token authorises calls on behalf of your company across every brand you own. It cannot reach brands owned by anyone else. Each request includes a :brand_slug — onpack 404s anything outside your scope.